/*
Theme Name:   Shakespeare Homes
Theme URI:    https://shakespearehomes.com
Description:  Astra child theme for Shakespeare Homes & Renovations Inc. Carries the design system, self-hosted typefaces and the GSAP motion layer. Every Elementor page on the site inherits these tokens, so adding the class reveal-item or img-reveal to any widget animates it exactly like the reference build.
Author:       BookedByAI
Author URI:   https://bookedbyai.ca
Template:     astra
Version:      1.126.0
License:      GNU General Public License v2 or later
Text Domain:  shakespeare-child
*/

/* ==========================================================================
   1. TYPEFACES, SELF-HOSTED
   Never called from Google Fonts. Speed, and privacy compliance.
   ========================================================================== */

@font-face{font-family:"Playfair Display";font-style:normal;font-weight:400;font-display:swap;src:url("assets/fonts/playfair-display-latin-400-normal.woff2") format("woff2")}
@font-face{font-family:"Playfair Display";font-style:normal;font-weight:500;font-display:swap;src:url("assets/fonts/playfair-display-latin-500-normal.woff2") format("woff2")}
@font-face{font-family:"Playfair Display";font-style:italic;font-weight:400;font-display:swap;src:url("assets/fonts/playfair-display-latin-400-italic.woff2") format("woff2")}
@font-face{font-family:"Playfair Display";font-style:italic;font-weight:500;font-display:swap;src:url("assets/fonts/playfair-display-latin-500-italic.woff2") format("woff2")}
@font-face{font-family:"Montserrat";font-style:normal;font-weight:300;font-display:swap;src:url("assets/fonts/montserrat-latin-300-normal.woff2") format("woff2")}
@font-face{font-family:"Montserrat";font-style:normal;font-weight:400;font-display:swap;src:url("assets/fonts/montserrat-latin-400-normal.woff2") format("woff2")}
@font-face{font-family:"Montserrat";font-style:normal;font-weight:500;font-display:swap;src:url("assets/fonts/montserrat-latin-500-normal.woff2") format("woff2")}
@font-face{font-family:"Montserrat";font-style:normal;font-weight:600;font-display:swap;src:url("assets/fonts/montserrat-latin-600-normal.woff2") format("woff2")}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url("assets/fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2")}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url("assets/fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2")}

/* ==========================================================================
   2. TOKENS
   Ported from the reference build's styles.css. Do not reinterpret.
   ========================================================================== */

:root{
  --shr-blue:#00549a;   /* 1.54.0. 20A: #0064b4 measured 5.54:1 on cream. This is 7.05:1. */
  /* 1.49.0. The blue reads at 5.5:1 on Chalk and at 2.6:1 on Deep Harbour,
     which is below the 4.5:1 a body of text needs. Every dark band on the
     site carried blue type. This is the same hue lightened until it reads at
     9:1 on Harbour, and it is used for type and for anything a visitor has to
     see on a dark ground. The blue stays exactly as it is on light grounds. */
  --shr-sky:#9cc8ec;
  --shr-harbour:#08243a;
  --shr-chalk:#f7f5f0;
  --shr-paper:#f0ebe0;
  --shr-ivory:#fbfaf7;
  --shr-slate:#44535f;  /* 1.54.0. 20A: #5a6b78 measured 5.06:1 on cream. This is 7.28:1. */
  --shr-fill:#b8c4ce;

  --shr-font-display:"Playfair Display",Georgia,serif;
  --shr-font-sans:"Montserrat",ui-sans-serif,system-ui,sans-serif;
  --shr-font-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,monospace;

  /* Nothing on this site is rounded. */
  --shr-radius:0px;

  --shr-measure-body:720px;
  --shr-measure-article:680px;
}

/* ==========================================================================
   3. BASE
   ========================================================================== */

html{-webkit-font-smoothing:antialiased}

body{
  background-color:var(--shr-chalk);
  color:var(--shr-harbour);
  font-family:var(--shr-font-sans);
  /* clip, not hidden. Found at 1.40.0: with html also clipped (section 8),
     hidden on the body no longer passes to the viewport, so the body became
     a scroll container that never scrolls, and every position:sticky on the
     site silently stopped sticking, including the team page's portraits.
     clip trims the same overflow without creating a scroll container. */
  overflow-x:clip;
  -webkit-tap-highlight-color:rgba(0,100,180,.15);
}

h1,h2,h3,
.entry-title,
.elementor-heading-title{
  font-family:var(--shr-font-display);
  font-weight:400;
  letter-spacing:.01em;
  line-height:1.1;
}

a{color:var(--shr-blue)}

::selection{background-color:var(--shr-blue);color:var(--shr-ivory)}

a:focus-visible,button:focus-visible,input:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--shr-blue);
  outline-offset:2px;
}

/* Corners are square sitewide, including anything Astra or Elementor rounds. */
button,input,select,textarea,
.ast-button,.elementor-button,.wp-block-button__link{
  border-radius:var(--shr-radius);
}

@media (max-width:767px){
  body{padding-bottom:calc(56px + env(safe-area-inset-bottom))}
}

/* Touch ergonomics: small inline links keep their visual size but reach 44px. */
@media (max-width:1023px){
  a,button{-webkit-tap-highlight-color:rgba(0,100,180,.15)}
  a.shr-mono-sm.shr-inline-block,
  a.shr-mono-sm:not(.shr-mono){
    padding-top:12px;padding-bottom:12px;
    display:inline-block;min-height:44px;
  }
}

/* iOS never zooms on focus: every field is at least 16px. */
@media (max-width:767px){
  input,select,textarea{font-size:16px !important}
}

/* ==========================================================================
   4. UTILITIES
   Add these as CSS classes on any Elementor widget.
   ========================================================================== */

.shr-mono{
  font-family:var(--shr-font-mono);
  text-transform:uppercase;
  letter-spacing:.14em;
  font-size:.75rem;
  line-height:1.5;
}

.shr-mono-sm{
  font-family:var(--shr-font-mono);
  text-transform:uppercase;
  letter-spacing:.14em;
  font-size:.75rem;
  line-height:1.5;
}

.shr-display{font-family:var(--shr-font-display)}

.shr-measure{max-width:var(--shr-measure-body);margin-left:auto;margin-right:auto}
.shr-measure-article{max-width:var(--shr-measure-article);margin-left:auto;margin-right:auto}

/* Graph-paper wash. */
.shr-paper-grain{
  background-color:#f0ebe0;
  background-image:
    repeating-linear-gradient(0deg,rgba(90,107,120,.05) 0 1px,transparent 1px 4px),
    repeating-linear-gradient(90deg,rgba(90,107,120,.04) 0 1px,transparent 1px 5px);
}

.shr-paper-grain-soft{
  background-color:#f0ebe0;
  background-image:
    repeating-linear-gradient(0deg,rgba(90,107,120,.02) 0 1px,transparent 1px 4px),
    repeating-linear-gradient(90deg,rgba(90,107,120,.016) 0 1px,transparent 1px 5px);
}

/* 30% lighter on phones. */
@media (max-width:767px){
  .shr-paper-grain-soft{
    background-image:
      repeating-linear-gradient(0deg,rgba(90,107,120,.014) 0 1px,transparent 1px 4px),
      repeating-linear-gradient(90deg,rgba(90,107,120,.011) 0 1px,transparent 1px 5px);
  }
}

/* Nav scrim: taller and darker on phones so the wordmark reads over any hero frame. */
.shr-nav-scrim{
  height:180px;
  background:linear-gradient(to bottom,rgba(8,36,58,.68),rgba(8,36,58,0));
}
@media (min-width:1024px){
  .shr-nav-scrim{
    height:160px;
    background:linear-gradient(to bottom,rgba(8,36,58,.6),rgba(8,36,58,0));
  }
}

/* Full-height sections use the small viewport height on mobile browsers so the
   bottom of the frame never hides under the URL bar or the sticky bar. */
.shr-h-hero{height:100vh;height:100svh}
@media (max-width:767px){
  /* Photo + control band + 56px sticky bar = exactly the full viewport. */
  .shr-h-hero{
    height:calc(100vh - 56px - env(safe-area-inset-bottom));
    height:calc(100svh - 56px - env(safe-area-inset-bottom));
  }
}

/* Deliberate mobile crops. */
@media (max-width:767px){
  .shr-crop-hero-01{object-position:50% 42%}
  .shr-crop-hero-02{object-position:50% 38%}
  .shr-crop-hero-03{object-position:50% 45%}
  .shr-crop-build-03{object-position:30% 50%}
  .shr-crop-statement{object-position:50% 45%}
  .shr-crop-hero-04{object-position:52% 50%}
  .shr-crop-hero-05{object-position:64% 50%}
  /* 1.91.0, the three interiors. At 390 the crop is horizontal only. Each is
     pulled to the side the subject sits on: Balmoral's island and view are
     centre-left of the frame, Canyon's vanity runs to the right into the
     bath, Poetry's fireplace anchors the left. */
  .shr-crop-hero-06{object-position:55% 50%}
  .shr-crop-hero-07{object-position:58% 50%}
  .shr-crop-hero-08{object-position:58% 50%}
}

/* <picture> must not break the layout of the image it wraps. */
picture{display:contents}

/* Hide the scrollbar on horizontally scrolling category tabs. */
.shr-no-scrollbar{scrollbar-width:none;-ms-overflow-style:none}
.shr-no-scrollbar::-webkit-scrollbar{display:none}

/* ==========================================================================
   5. MOTION
   "from" states are set in JavaScript only, never in CSS, so a script failure
   leaves content visible rather than invisible.
   ========================================================================== */

.img-reveal{will-change:transform}

@media (prefers-reduced-motion:reduce){
  .reveal-item{opacity:1 !important;transform:none !important}
  .img-reveal{transform:none !important}
}

/* ==========================================================================
   6. ASTRA INTEGRATION
   Astra prints its own dynamic CSS from the Customizer. Rather than fight it
   selector by selector, we redefine the global colour variables it and every
   Elementor widget read from. One place, whole site.
   ========================================================================== */

:root,
body,
.ast-separate-container{
  --ast-global-color-0:#0064b4;  /* Shakespeare Blue. The only accent */
  --ast-global-color-1:#08243a;  /* Deep Harbour, hover */
  --ast-global-color-2:#08243a;  /* Body text */
  --ast-global-color-3:#08243a;  /* Headings */
  --ast-global-color-4:#f7f5f0;  /* Warm Chalk, site background */
  --ast-global-color-5:#fbfaf7;  /* Ivory, alternate surface */
  --ast-global-color-6:#f0ebe0;  /* Paper, subtle surface */
  --ast-global-color-7:#b8c4ce;  /* Fill, borders */
  --ast-global-color-8:#5a6b78;  /* Slate, secondary text */
  --ast-border-color:#b8c4ce;
}

/* Astra's dynamic CSS sets the page background at a specificity this has to
   meet. Warm Chalk everywhere, never plain white. */
html,
body,
.site,
.ast-separate-container,
.ast-page-builder-template .site-content,
.ast-plain-container .site-content{
  background-color:var(--shr-chalk);
}

/* No card. The reference build has no boxed content panel anywhere: Warm Chalk
   runs edge to edge and sections step into Deep Harbour, Paper or Ivory on
   purpose. Astra's boxed article is switched off in functions.php; this makes
   sure nothing paints a panel even if a layout slips through. */
.ast-separate-container .ast-article-single,
.ast-separate-container .ast-article-post,
.ast-separate-container .comments-area,
.ast-separate-container .ast-comment-list li.depth-1,
.ast-article-single,
.ast-article-post{
  background-color:transparent;
  box-shadow:none;
}

/* Astra rounds things by default. Nothing on this site is rounded. */
.ast-button,.ast-custom-button,
.wp-block-button__link,
.elementor-button,
.ast-separate-container .ast-article-single,
input,select,textarea{
  border-radius:var(--shr-radius) !important;
}

/* Secondary text in Slate, per the palette. */
.entry-meta,.entry-meta *,
.ast-excerpt-container,
.post-meta{
  color:var(--shr-slate);
  font-family:var(--shr-font-mono);
  text-transform:uppercase;
  letter-spacing:.14em;
  font-size:.75rem;
}

/* ==========================================================================
   7. TEMPORARY, UNTIL THE REAL TEMPLATES LAND
   Astra's blog furniture is showing through on content types that are not
   blog posts. These rules suppress the worst of it so the site is not
   embarrassing to look at mid-build. Every one of them becomes redundant when
   the real templates are built and should be deleted then.
   ========================================================================== */

/* Author byline and date do not belong on a project, an award, a testimonial
   or an FAQ. As of 1.2.0 these are removed from the MARKUP in functions.php,
   not merely hidden. This block is a fallback for any wrapper element that
   survives with nothing in it. Deleted when the real templates land. */
.single-work .entry-meta,
.single-award .entry-meta,
.single-faq .entry-meta,
.single-testimonial .entry-meta,
.single-in-the-news .entry-meta,
.single-slider .entry-meta,
.post-type-archive-work .entry-meta,
.post-type-archive-award .entry-meta,
.post-type-archive-in-the-news .entry-meta{
  display:none;
}

/* Blog-style previous/next post navigation does not belong on them either. */
.single-work .post-navigation,
.single-award .post-navigation,
.single-faq .post-navigation,
.single-testimonial .post-navigation,
.single-in-the-news .post-navigation{
  display:none;
}

/* ==========================================================================
   8. SITE CHROME
   Header, mobile menu, contact rail, sticky bar, footer.
   Ported from Nav.tsx and Footer.tsx.
   ========================================================================== */

/* Astra's own header and footer are removed in chrome.php where the theme
   allows it. This is the fallback for the case where a future Astra update
   renames those functions: the page must never show two of either. */
.site-header,
.ast-above-header,
.ast-below-header,
.site-footer,
.ast-small-footer,
.ast-mobile-header-wrap{
  display:none !important;
}

.shr-skip{
  position:absolute;left:-9999px;top:0;z-index:200;
  background:var(--shr-harbour);color:var(--shr-ivory);
  padding:14px 20px;font-family:var(--shr-font-mono);
  text-transform:uppercase;letter-spacing:.14em;font-size:.75rem;
}
.shr-skip:focus{left:0}

/* ---- Header ------------------------------------------------------------ */

.shr-header{
  position:fixed;inset-inline:0;top:0;z-index:120;
  background-color:transparent;
  border-bottom:1px solid transparent;
  transition:background-color .4s ease,border-color .4s ease;
}
.shr-header[data-solid="true"]{
  background-color:var(--shr-chalk);
  border-bottom-color:var(--shr-blue);
}
.shr-header[data-menu="open"]{
  background-color:transparent;
  border-bottom-color:transparent;
}

.shr-nav-scrim{
  position:absolute;inset-inline:0;top:0;pointer-events:none;
  height:180px;
  background:linear-gradient(to bottom,rgba(8,36,58,.68),rgba(8,36,58,0));
  transition:opacity .4s ease;
}
@media (min-width:1024px){
  .shr-nav-scrim{height:160px;background:linear-gradient(to bottom,rgba(8,36,58,.6),rgba(8,36,58,0))}
}
.shr-header[data-solid="true"] .shr-nav-scrim,
.shr-header[data-menu="open"] .shr-nav-scrim{opacity:0}

.shr-header__inner{
  position:relative;
  max-width:1560px;margin:0 auto;
  display:flex;align-items:center;justify-content:space-between;gap:24px;
  padding:16px 20px;
}
@media (min-width:768px){ .shr-header__inner{padding:16px 40px} }

.shr-brand{display:flex;align-items:center;gap:12px;text-decoration:none;flex-shrink:0}

/* The two colourways stack in one place. Only the light mark occupies flow;
   the dark one is absolutely positioned over it and they cross-fade. Letting
   both sit in flow is what put the dark wordmark across the nav links in
   1.7.0. */
.shr-brand__logo{position:relative;display:block;height:36px;line-height:0;flex-shrink:0}
@media (min-width:1024px){ .shr-brand__logo{height:48px} }
@media (min-width:1440px){ .shr-brand__logo{height:60px} }

.shr-brand__mark{height:100%;width:auto;display:block;transition:opacity .4s ease}
.shr-brand__mark--dark{position:absolute;top:0;left:0;opacity:0;pointer-events:none}
.shr-header[data-solid="true"] .shr-brand__mark--light{opacity:0}
.shr-header[data-solid="true"] .shr-brand__mark--dark{opacity:1}
.shr-header[data-menu="open"] .shr-brand__mark--light{opacity:1}
.shr-header[data-menu="open"] .shr-brand__mark--dark{opacity:0}
.shr-brand__dots{color:var(--shr-ivory)}
.shr-header[data-solid="true"] .shr-brand__dots{color:var(--shr-blue)}

.shr-nav{display:none;align-items:center;gap:28px;flex-shrink:0}
@media (min-width:1024px){ .shr-nav{display:flex} }
@media (min-width:1280px){ .shr-nav{gap:36px} }
.shr-nav a{
  white-space:nowrap;
  font-family:var(--shr-font-sans);font-size:13px;
  text-transform:uppercase;letter-spacing:.14em;text-decoration:none;
  color:var(--shr-ivory);text-shadow:0 1px 3px rgba(8,36,58,.45);
  transition:color .3s ease;
}
.shr-header[data-solid="true"] .shr-nav a{color:var(--shr-harbour);text-shadow:none}
.shr-nav a:hover{color:var(--shr-blue)}
/* 1.52.0. 13px of uppercase is a 21px target. The padding makes it 45. */
.shr-nav a{display:inline-block;padding:12px 0}

.shr-header__actions{display:none;align-items:center;gap:24px;flex-shrink:0}
@media (min-width:1024px){ .shr-header__actions{display:flex} }
.shr-header__phone{
  white-space:nowrap;
  font-family:var(--shr-font-sans);font-size:13px;letter-spacing:.06em;
  color:var(--shr-ivory);text-decoration:none;text-shadow:0 1px 3px rgba(8,36,58,.45);
}
.shr-header[data-solid="true"] .shr-header__phone{color:var(--shr-harbour);text-shadow:none}

/* ---- The button -------------------------------------------------------- */

.shr-pill{
  white-space:nowrap;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;
  display:inline-flex;align-items:center;gap:10px;
  padding:14px 24px;text-decoration:none;
  border:1px solid transparent;border-radius:0;
  transition:background-color .3s ease,color .3s ease,border-color .3s ease;
}
.shr-pill--outline{border-color:var(--shr-blue);color:var(--shr-blue);background:transparent}
.shr-pill--outline:hover{background:var(--shr-blue);color:var(--shr-ivory)}
.shr-pill--solid{background:var(--shr-blue);color:var(--shr-ivory)}
.shr-pill--solid:hover{background:var(--shr-harbour)}
.shr-pill--white{background:var(--shr-ivory);color:var(--shr-harbour)}
.shr-pill--white:hover{background:var(--shr-blue);color:var(--shr-ivory)}
.shr-pill--harbour{background:var(--shr-harbour);color:var(--shr-ivory)}
.shr-pill--harbour:hover{background:var(--shr-blue)}
.shr-header[data-solid="true"] .shr-header__cta{
  background:transparent;border-color:var(--shr-blue);color:var(--shr-blue);
}
.shr-header[data-solid="true"] .shr-header__cta:hover{background:var(--shr-blue);color:var(--shr-ivory)}

/* ---- Burger ------------------------------------------------------------ */

.shr-burger{
  position:relative;display:flex;align-items:center;justify-content:center;
  height:48px;width:48px;margin-right:-8px;
  background:none;border:0;cursor:pointer;padding:0;
}
@media (min-width:1024px){ .shr-burger{display:none} }
.shr-burger__bar{
  position:absolute;display:block;height:2px;width:22px;
  background-color:var(--shr-ivory);
  filter:drop-shadow(0 1px 2px rgba(8,36,58,.5));
  transition:transform .3s ease,background-color .3s ease;
}
.shr-burger__bar:nth-child(1){transform:translateY(-4.5px)}
.shr-burger__bar:nth-child(2){transform:translateY(4.5px)}
.shr-header[data-solid="true"] .shr-burger__bar{background-color:var(--shr-harbour);filter:none}
.shr-header[data-menu="open"] .shr-burger__bar{background-color:var(--shr-ivory);filter:drop-shadow(0 1px 2px rgba(8,36,58,.5))}
.shr-header[data-menu="open"] .shr-burger__bar:nth-child(1){transform:rotate(45deg)}
.shr-header[data-menu="open"] .shr-burger__bar:nth-child(2){transform:rotate(-45deg)}

/* ---- Mobile menu ------------------------------------------------------- */

.shr-mobile{
  position:fixed;inset:0;z-index:110;overflow-y:auto;
  background-color:var(--shr-harbour);
  clip-path:circle(0% at 100% 0%);
  visibility:hidden;
  transition:clip-path .5s cubic-bezier(.76,0,.24,1),visibility 0s linear .5s;
}
.shr-mobile[aria-hidden="false"]{
  clip-path:circle(150% at 100% 0%);
  visibility:visible;
  transition:clip-path .5s cubic-bezier(.76,0,.24,1),visibility 0s linear 0s;
}
@media (min-width:1024px){ .shr-mobile{display:none} }

.shr-mobile__inner{
  display:flex;flex-direction:column;min-height:100%;
  padding:92px 24px calc(40px + env(safe-area-inset-bottom));
}
.shr-mobile__list{list-style:none;margin:0;padding:0}
.shr-mobile__list li{border-bottom:1px solid rgba(251,250,247,.15)}
.shr-mobile__list a{
  display:flex;align-items:center;min-height:56px;padding:8px 0;
  font-family:var(--shr-font-display);font-size:34px;line-height:1.15;
  color:var(--shr-ivory);text-decoration:none;
  transform:translateY(24px);opacity:0;
  transition:transform .45s cubic-bezier(.22,1,.36,1),opacity .45s ease;
}
.shr-mobile[aria-hidden="false"] .shr-mobile__list a{
  transform:translateY(0);opacity:1;
  transition-delay:calc(.2s + var(--i) * .06s);
}
.shr-mobile__foot{margin-top:40px;border-top:1px solid var(--shr-blue);padding-top:32px}
.shr-mobile__phone{
  display:inline-flex;align-items:center;min-height:44px;
  font-family:var(--shr-font-sans);font-size:18px;
  color:var(--shr-ivory);text-decoration:none;
}
.shr-mobile__addr{margin-top:12px;color:rgba(251,250,247,.7)}
.shr-mobile__cta{
  display:flex;align-items:center;justify-content:center;gap:10px;
  min-height:56px;width:100%;margin-top:28px;padding:0 24px;
  background:var(--shr-blue);color:var(--shr-ivory);text-decoration:none;
}
.shr-mobile__tagline{
  margin-top:auto;padding-top:48px;
  font-family:var(--shr-font-display);font-style:italic;font-size:18px;
  line-height:1.6;color:rgba(251,250,247,.6);
}

/* ---- Desktop contact rail ---------------------------------------------- */

.shr-rail{
  position:fixed;right:0;top:50%;transform:translateY(-50%);z-index:90;
  display:none;flex-direction:column;width:52px;
  background-color:rgba(8,36,58,.92);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  border-left:1px solid var(--shr-blue);
}
@media (min-width:768px){ .shr-rail{display:flex} }
.shr-rail a{
  position:relative;display:flex;align-items:center;justify-content:center;
  height:52px;width:52px;color:var(--shr-ivory);
  transition:background-color .3s ease;
}
.shr-rail a + a{border-top:1px solid rgba(251,250,247,.12)}
.shr-rail a:hover,.shr-rail a:focus-visible{background-color:var(--shr-blue)}
.shr-rail .shr-icon{height:20px;width:20px}
.shr-rail__label{
  position:absolute;right:100%;top:50%;transform:translateY(-50%);
  display:flex;align-items:center;height:44px;padding:0 16px;
  white-space:nowrap;color:var(--shr-ivory);
  background-color:rgba(8,36,58,.92);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  opacity:0;pointer-events:none;transition:opacity .35s ease-out;
}
.shr-rail a:hover .shr-rail__label,
.shr-rail a:focus-visible .shr-rail__label{opacity:1}

/* Keep the rail from ever overlapping section content. */
@media (min-width:1024px){
  .shr-footer__inner,.shr-footer__base{padding-right:72px}
}

/* ---- Mobile sticky bar -------------------------------------------------- */

.shr-stickybar{
  position:fixed;inset-inline:0;bottom:0;z-index:95;
  display:grid;grid-template-columns:1fr 1fr;
  border-top:1px solid var(--shr-blue);
  padding-bottom:env(safe-area-inset-bottom);
}
@media (min-width:768px){ .shr-stickybar{display:none} }
.shr-stickybar a{
  display:flex;align-items:center;justify-content:center;
  min-height:56px;font-size:12px;color:var(--shr-ivory);text-decoration:none;
}
.shr-stickybar a:first-child{background:var(--shr-harbour)}
.shr-stickybar a:last-child{background:var(--shr-blue)}

/* ---- Footer ------------------------------------------------------------- */

.shr-footer{background-color:var(--shr-harbour)}
.shr-footer__ridge{background-color:var(--shr-chalk);line-height:0}
.shr-footer__ridge .shr-ridgeline{display:block;width:100%;height:72px;color:var(--shr-blue)}
@media (min-width:768px){ .shr-footer__ridge .shr-ridgeline{height:180px} }

.shr-footer__inner{max-width:1560px;margin:0 auto;padding:64px 20px}
@media (min-width:768px){ .shr-footer__inner{padding:96px 40px} }

.shr-footer__grid{display:grid;gap:48px}
@media (min-width:1024px){ .shr-footer__grid{grid-template-columns:1fr 2fr;gap:56px} }

.shr-footer__mark{display:flex;align-items:center;gap:16px}
.shr-footer__mark img{width:260px;max-width:100%;height:auto;display:block}
.shr-footer__mark .shr-dots{color:var(--shr-ivory)}
.shr-footer__tagline{
  margin-top:32px;font-family:var(--shr-font-display);font-style:italic;
  font-size:22px;color:var(--shr-ivory);
}
.shr-footer__social{display:flex;gap:20px;margin-top:40px;color:var(--shr-blue)}
.shr-footer__social a{color:inherit;transition:color .3s ease}
.shr-footer__social a:hover{color:var(--shr-ivory)}
.shr-footer__social .shr-icon{height:20px;width:20px}

.shr-footer__cols{display:grid;grid-template-columns:1fr;gap:40px}
@media (min-width:401px){ .shr-footer__cols{grid-template-columns:repeat(2,1fr)} }
@media (min-width:1024px){ .shr-footer__cols{grid-template-columns:repeat(4,1fr)} }
.shr-footer__colhead{color:var(--shr-blue)}
.shr-footer__cols ul{list-style:none;margin:20px 0 0;padding:0}
.shr-footer__cols li{
  font-family:var(--shr-font-sans);font-size:13px;line-height:1.7;
  color:rgba(251,250,247,.75);margin-bottom:10px;
}
.shr-footer__cols a{color:inherit;text-decoration:none;transition:color .3s ease}
.shr-footer__cols a:hover{color:var(--shr-blue)}

.shr-footer__base{border-top:1px solid var(--shr-blue);padding:24px 20px}
@media (min-width:768px){ .shr-footer__base{padding:24px 40px} }
.shr-footer__base p{max-width:1560px;margin:0 auto;color:rgba(251,250,247,.6)}

/* ---- Fixed header clearance -------------------------------------------- */
/* The home page hero sits under the transparent header on purpose. Every
   other template needs to clear it. */
body:not(.home) .site-content{padding-top:88px}
@media (min-width:1024px){ body:not(.home) .site-content{padding-top:108px} }

@media (prefers-reduced-motion:reduce){
  .shr-mobile,.shr-mobile__list a,.shr-header,.shr-brand__mark,
  .shr-burger__bar,.shr-rail a,.shr-rail__label,.shr-pill{
    transition-duration:.01ms !important;
  }
}

/* ---- Fixes found in review ---------------------------------------------- */

/* The WordPress admin bar pushes the page down for logged-in users and was
   clipping the top of the wordmark. Visitors never see this, the team does. */
body.admin-bar .shr-header{top:32px}
@media screen and (max-width:782px){ body.admin-bar .shr-header{top:46px} }

/* Astra's featured-image section was 1335px wide inside a 1135px viewport,
   which put 100px of horizontal scroll on the whole document. clip rather than
   hidden, so position:sticky keeps working anywhere we use it later. */
html{overflow-x:clip}
.ast-single-post-featured-section,
.post-thumb,
.ast-article-single,
.site-content{max-width:100%}
.ast-single-post-featured-section img,
.post-thumb img,
.entry-content img,
.wp-post-image{max-width:100%;height:auto}

/* ==========================================================================
   9. THE PINNED HERO
   Ported from Hero.tsx. The photograph fills the frame, three lines fade
   through on a scrubbed scroll, and on phones the bottom 26% becomes a Deep
   Harbour control band that meets the sticky bar exactly.
   ========================================================================== */

.shr-hero{
  position:relative;width:100%;overflow:hidden;
  background-color:var(--shr-harbour);
}

/* Photograph: top 74% on phones so the control band has its own space,
   full bleed from 768px up. */
.shr-hero__plate{
  position:absolute;inset-inline:0;top:0;height:74%;overflow:hidden;
  will-change:transform;
}
@media (min-width:768px){ .shr-hero__plate{inset:0;height:100%} }

.shr-hero__img{
  position:absolute;inset:0;height:100%;width:100%;
  object-fit:cover;opacity:0;
  transition:opacity 1.2s ease-in-out;
}

/* 1.53.0. THE HERO IS BACK TO THE BUILD THAT WON THE JOB.

   Nothing is laid over the photograph while the headline runs. Not a band,
   not a plate, not a grade. Quentin's note: the tint was never in the original
   build and the original is what everyone liked. He is right, and the reason
   it kept coming back is that I was answering a contrast number rather than
   looking at the page.

   The veil is exactly what it was: the bottom third, so the control band has
   somewhere to sit. Everything above it is the picture.

   Legibility is handled at the type instead, where it costs the photograph
   nothing: Ivory at 112px with a close, tight shadow reads on anything in the
   frame set. That shadow is 2px and 10px, not a glow. */
.shr-hero__veil{
  position:absolute;inset-inline:0;bottom:0;height:33.333%;
  background:linear-gradient(to top,rgba(8,36,58,.72),rgba(8,36,58,0));
}
.shr-hero__grade{ display:none; }
.shr-hero__line{
  text-shadow:0 2px 10px rgba(8,36,58,.55), 0 1px 2px rgba(8,36,58,.45);
}

.shr-hero__lines{
  position:absolute;inset-inline:0;top:0;height:74%;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:2px;
  padding:0 24px;pointer-events:none;
}
@media (min-width:768px){ .shr-hero__lines{inset:0;height:100%} }

/* 1.51.1. What is written here is the state with no JavaScript: the three
   lines printed as one headline, centred in the frame, each on its own scrim.
   The script overrides it and brings them in one at a time on the scroll.
   Writing it in this order is what stops the headline flashing on and then
   off again while the page is still loading. */
.shr-hero__line{
  position:relative;max-width:100%;padding:0;
  text-align:center;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(2.25rem,11vw,3.5rem);line-height:1.05;
  letter-spacing:.01em;
  color:var(--shr-ivory);
}

/* The scrim belongs to the line, so it arrives with the words and leaves with
   them: the photograph is never darkened where there is nothing to read. It is
   a wash across the frame rather than a plate behind the letters, which is the
   difference between light falling off and a box drawn on a picture. Deep
   Harbour at .86 under Ivory holds past 9:1 on a white sky, which is brighter
   than any frame in the set. */
.shr-hero__line{isolation:isolate}
.shr-hero__lineinner{
  position:relative;z-index:1;
  display:block;max-width:100%;
}

/* 1.52.0. No band, no plate, no shape of any kind behind the words.
   1.51.1 put a wash behind the headline that arrived with it, and on a dusk
   photograph it read as a blue box drawn across the frame. Cheap, and Quentin
   was right to call it. The photograph is graded instead, once, top to bottom,
   as a photograph in a film is graded: it is always there, it has no edges to
   notice, and it does the same job. See .shr-hero__veil below. */
.shr-hero__lines::before{ content:none; }

@media (min-width:768px){
  .shr-hero__line{font-size:clamp(3rem,8vw,7rem);line-height:1.1}
}

/* The heading. It is not one of the animated lines and it never was going to
   survive being one, so it stands on its own: always in the markup, always in
   the accessibility tree, never painted over the photograph. */
.shr-hero__h1{
  position:absolute;width:1px;height:1px;
  margin:-1px;padding:0;border:0;
  overflow:hidden;white-space:nowrap;
  clip:rect(0 0 0 0);clip-path:inset(50%);
}

/* With JavaScript, and unless the visitor has asked for reduced motion, the
   lines stack on top of one another and start hidden. home.js fades them up
   one at a time against the scroll. Nothing is on screen at load: that is the
   point of the sequence, and 1.51.0 lost it. */
.shr-js .shr-hero:not([data-still]) .shr-hero__lines{
  display:block;
}

.shr-js .shr-hero:not([data-still]) .shr-hero__line{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  padding:0 24px;
  opacity:0;visibility:hidden;
}
.shr-js .shr-hero:not([data-still]) .shr-hero__line::before{ content:none; }


/* Mobile control band: Deep Harbour, meets the 56px sticky bar exactly. */
.shr-hero__band{
  position:absolute;inset-inline:0;bottom:0;height:26%;
  display:flex;flex-direction:column;justify-content:flex-end;
  background-color:var(--shr-harbour);
}
@media (min-width:768px){
  .shr-hero__band{
    height:auto;background-color:transparent;
    padding:0 40px 40px;gap:24px;
  }
}
.shr-hero__bandrow{
  display:flex;flex:1;align-items:center;justify-content:space-between;
  gap:16px;padding:0 24px;
}
@media (min-width:768px){
  .shr-hero__bandrow{flex:none;align-items:flex-end;gap:24px;padding:0}
}
.shr-hero__cta{font-size:12px;white-space:nowrap}
@media (min-width:768px){ .shr-hero__cta{font-size:.75rem} }
.shr-hero__scroll{color:rgba(251,250,247,.6)}
@media (min-width:768px){ .shr-hero__scroll{color:rgba(251,250,247,.8)} }
.shr-hero__spacer{display:none}
@media (min-width:768px){ .shr-hero__spacer{display:block;width:180px} }

/* Segmented progress bar, shared later with the testimonial slider. */
.shr-segbar{display:flex;width:100%;align-items:center;gap:12px}
@media (min-width:768px){ .shr-segbar{margin-top:24px} }
.shr-segbar__seg{
  position:relative;height:3px;flex:1;padding:0;border:0;
  background-color:rgba(251,250,247,.35);
  overflow:hidden;cursor:pointer;
}
.shr-segbar__seg span{
  position:absolute;inset-block:0;left:0;width:100%;
  background-color:var(--shr-blue);
  transform:scaleX(0);transform-origin:left;
}
.shr-segbar__seg.is-active span{
  /* 1.52.0. 18A-4 0f: this filled itself over four seconds after load, which
     is the last thing on the page that moved without being asked. The active
     segment is simply full. */
  transform:scaleX(1);
}
@keyframes shr-fill{from{transform:scaleX(0)}to{transform:scaleX(1)}}

@media (prefers-reduced-motion:reduce){
  .shr-hero__img{transition:none}
  .shr-segbar__seg span{animation:none;transform:scaleX(1)}
  .shr-segbar__seg{cursor:default}
}

/* Scaffolding: the page's own content below the hero until sections 3 to 16
   land. Deleted in the next release. */
.shr-legacy-content{padding:64px 20px}
@media (min-width:768px){ .shr-legacy-content{padding:96px 40px} }

/* The hero sits under the transparent header on purpose, so the front page
   must not take the clearance padding the other templates get. */
body.home .site-content{padding-top:0}

/* ==========================================================================
   10. FRONT PAGE, FULL BLEED
   Asking Astra for its page-builder layout should be enough on its own. This
   is the belt to that braces: three attempts at naming an Astra internal have
   already missed in this build, so the front page is forced out of the
   container here as well. Scoped to body.home, so nothing else is affected.
   ========================================================================== */

body.home .site-content,
body.home .site-content > .ast-container,
body.home .ast-container,
body.home #primary,
body.home .content-area,
body.home .ast-page-builder-template .entry-content{
  display:block !important;
  width:100% !important;
  max-width:none !important;
  margin-left:0 !important;
  margin-right:0 !important;
  padding-left:0 !important;
  padding-right:0 !important;
}

/* The hero must never be a shrinkable flex child. */
.shr-hero{
  flex:none !important;
  width:100% !important;
  max-width:none !important;
  align-self:stretch;
}

/* The rail's 72px reservation is for text columns, not the full-bleed hero. */
@media (min-width:1024px){
  body.home .site-content{padding-right:0}
}

/* ==========================================================================
   11. MOBILE HERO BAND, ANCHORED RATHER THAN MEASURED
   The band was given height:26% and bottom:0, which meant its bottom edge
   depended on the hero's own height being exactly right. It was not: the
   sticky bar is 57px, not 56, because of its 1px top border, and GSAP writes
   inline dimensions when it pins, so any drift at measure time gets frozen in.
   The band ate the bottom 47px of itself and buried the segmented bars under
   the CALL bar.

   Anchoring the band to both edges instead removes the arithmetic entirely.
   Whatever the hero measures, the band starts at 74% and stops exactly on top
   of the sticky bar.
   ========================================================================== */

:root{
  /* 56px of tap target plus the 1px top border. */
  --shr-sticky-h:57px;
}

@media (max-width:767px){
  /* Full viewport. The band's own anchoring keeps it clear of the bar now, so
     the hero no longer has to subtract anything. */
  .shr-h-hero{
    height:100vh;
    height:100svh;
  }

  .shr-hero__band{
    top:74%;
    bottom:calc(var(--shr-sticky-h) + env(safe-area-inset-bottom));
    height:auto;
  }

  /* Breathing room so the bars never sit flush against the bar above them. */
  .shr-hero__band .shr-segbar{margin-bottom:14px}
  .shr-hero__bandrow{padding-bottom:4px}
}

/* ==========================================================================
   12. THE ADMIN BAR, AND THE HERO
   The hero is 100svh tall but body.admin-bar pushes it down, so its bottom
   edge lands below the viewport by exactly the admin bar's height. The band is
   anchored to the hero's bottom edge, so it went off-screen with it and the
   segmented bars ended up under the sticky CALL bar.

   A logged-out visitor never had this: hero top 0, bottom 100svh, band bottom
   landing exactly on the sticky bar. It only bites for anyone logged into
   wp-admin, which is the whole team and every test.

   The header already offsets for this. The hero now does too.
   ========================================================================== */

body.admin-bar .shr-h-hero{
  height:calc(100vh - 32px);
  height:calc(100svh - 32px);
}

@media screen and (max-width:782px){
  body.admin-bar .shr-h-hero{
    height:calc(100vh - 46px);
    height:calc(100svh - 46px);
  }
}

/* The band must never be crushed to nothing, whatever the viewport does. */
@media (max-width:767px){
  .shr-hero__band{min-height:132px}
}

/* ==========================================================================
   13. HOME SECTIONS 3 TO 8
   Opening statement, three pillars, what we build, manifesto, statement
   moment. Ported from routes/index.tsx.
   ========================================================================== */

.shr-eyebrow{margin:0}
.shr-eyebrow--blue{color:var(--shr-blue)}
.shr-eyebrow--ivory{color:rgba(251,250,247,.7)}

/* ---- 3. Opening statement ---------------------------------------------- */

.shr-opening{background-color:var(--shr-chalk);padding:64px 24px;text-align:center}
@media (min-width:768px){ .shr-opening{padding:176px 40px} }
.shr-opening__inner{max-width:900px;margin:0 auto}
.shr-opening__quote{
  margin:32px 0 0;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.375rem,6vw,1.75rem);line-height:1.4;
  letter-spacing:.01em;color:var(--shr-harbour);
}
@media (min-width:768px){
  .shr-opening__quote{margin-top:40px;font-size:clamp(1.5rem,3.2vw,2.6rem);line-height:1.35}
}
.shr-opening__sig{margin-top:40px}
@media (min-width:768px){ .shr-opening__sig{margin-top:48px} }
.shr-opening__rule{display:block;width:56px;height:1px;margin:0 auto;background:var(--shr-blue)}
.shr-opening__name{margin:24px 0 0;font-family:var(--shr-font-display);font-size:20px;color:var(--shr-harbour)}
.shr-opening__role{margin:8px 0 0;font-size:12px;color:var(--shr-slate)}

/* ---- 4. Three pillars --------------------------------------------------- */

.shr-pillars{background-color:var(--shr-chalk);padding:0 20px 64px}
@media (min-width:768px){ .shr-pillars{padding:0 40px 160px} }
.shr-pillars__grid{max-width:1400px;margin:0 auto;display:grid;gap:48px}
@media (min-width:768px){ .shr-pillars__grid{grid-template-columns:repeat(3,1fr);gap:40px} }
.shr-pillar{text-align:center}
.shr-pillar__hair{display:none;width:100%;height:1px;background:rgba(90,107,120,.4)}
@media (min-width:768px){ .shr-pillar__hair{display:block} }
.shr-pillar__tick{display:block;width:24px;height:2px;margin:0 auto;background:var(--shr-blue)}
@media (min-width:768px){ .shr-pillar__tick{margin-top:24px} }
.shr-pillar h3{
  margin:20px 0 0;font-family:var(--shr-font-display);font-size:32px;color:var(--shr-harbour);
}
@media (min-width:768px){ .shr-pillar h3{margin-top:32px;font-size:36px} }
.shr-pillar p{margin:16px 0 0;color:var(--shr-slate)}

/* ---- 5. What we build --------------------------------------------------- */

.shr-build{position:relative;overflow:hidden;background-color:var(--shr-chalk);padding:64px 0}
@media (min-width:768px){ .shr-build{padding:128px 40px} }
.shr-build__inner{position:relative;z-index:10;max-width:1400px;margin:0 auto}

.shr-build__head{display:grid;gap:32px;padding:0 24px}
@media (min-width:768px){
  .shr-build__head{grid-template-columns:repeat(2,1fr);align-items:end;gap:40px;padding:0}
}
.shr-build__head h2{
  margin:0;font-family:var(--shr-font-display);
  font-size:clamp(2.6rem,6.5vw,6rem);color:var(--shr-harbour);
}
.shr-build__head p{
  margin:0;font-family:var(--shr-font-sans);font-size:16px;line-height:1.7;color:var(--shr-slate);
}
@media (min-width:768px){ .shr-build__head p{max-width:28rem;justify-self:end} }

.shr-build__list{margin-top:48px;display:flex;flex-direction:column;gap:72px}
@media (min-width:768px){ .shr-build__list{margin-top:96px;gap:160px} }

.shr-build__entry{position:relative;display:grid;gap:32px;align-items:center}
@media (min-width:768px){
  .shr-build__entry{grid-template-columns:repeat(12,1fr);gap:64px}
  .shr-build__copy{grid-column:span 6}
  .shr-build__figure{grid-column:span 6}
  .shr-build__entry--left .shr-build__copy{order:2}
  .shr-build__entry--left .shr-build__figure{order:1}
  .shr-build__entry:not(.is-wide) .shr-build__figure{padding:0 24px}
}

.shr-build__ghost{
  display:none;position:absolute;top:-64px;left:0;pointer-events:none;
  font-family:var(--shr-font-display);font-size:180px;line-height:1;
  color:var(--shr-slate);opacity:.12;
}
@media (min-width:768px){ .shr-build__ghost{display:block} }

.shr-build__copy{position:relative;z-index:10;padding:0 24px}
@media (min-width:768px){ .shr-build__copy{padding:0} }
.shr-build__num{
  display:block;font-family:var(--shr-font-display);font-size:72px;line-height:1;
  color:var(--shr-slate);opacity:.3;
}
@media (min-width:768px){ .shr-build__num{display:none} }
.shr-build__copy .shr-eyebrow{margin-top:16px}
@media (min-width:768px){ .shr-build__copy .shr-eyebrow{margin-top:0} }
.shr-build__copy h3{
  margin:16px 0 0;font-family:var(--shr-font-display);
  font-size:clamp(1.8rem,3.4vw,3rem);color:var(--shr-harbour);
}
@media (min-width:768px){ .shr-build__copy h3{margin-top:20px} }
.shr-build__copy p{
  margin:20px 0 0;max-width:32rem;
  font-family:var(--shr-font-sans);font-size:16px;line-height:1.7;color:var(--shr-slate);
}
@media (min-width:768px){ .shr-build__copy p{margin-top:24px} }
.shr-build__link{
  display:inline-block;margin-top:16px;color:var(--shr-blue);text-decoration:none;
}
@media (min-width:768px){ .shr-build__link{margin-top:32px} }
.shr-build__link:hover{text-decoration:underline}
.shr-build__figure{overflow:hidden}
.shr-build__figure img{display:block;width:100%;height:auto;object-fit:cover}

/* ---- 7. Manifesto -------------------------------------------------------- */

.shr-manifesto{
  position:relative;overflow:hidden;
  background-color:var(--shr-harbour);padding:64px 20px;
}
@media (min-width:768px){ .shr-manifesto{padding:160px 40px} }
.shr-manifesto__shapes{position:absolute;inset:0;pointer-events:none}
.shr-manifesto__shapes span{
  position:absolute;display:block;background:#0f3450;filter:blur(28px);
  clip-path:polygon(12% 0%,100% 18%,84% 100%,0% 74%);
}
.shr-manifesto__inner{position:relative;max-width:1400px;margin:0 auto}
.shr-manifesto__inner .shr-eyebrow{color:var(--shr-blue)}
.shr-manifesto__cols{margin-top:48px;display:grid;gap:48px}
@media (min-width:768px){ .shr-manifesto__cols{grid-template-columns:repeat(2,1fr);gap:80px} }
.shr-manifesto__cols p{
  margin:0;font-family:var(--shr-font-sans);font-size:17px;line-height:1.8;color:var(--shr-ivory);
}
.shr-manifesto__memowrap{margin-top:80px;display:flex;justify-content:flex-end}

.shr-memo{position:relative;width:100%;max-width:24rem;transform:rotate(-2deg)}
.shr-memo__clip{
  position:absolute;left:20px;top:-20px;z-index:20;height:40px;width:20px;color:var(--shr-slate);
}
.shr-memo__sheet{position:relative;overflow:hidden;padding:28px}
.shr-memo__rules{
  position:absolute;inset:28px;pointer-events:none;
  background-image:repeating-linear-gradient(180deg,rgba(90,107,120,.16) 0 1px,transparent 1px 30px);
}
.shr-memo__label{position:relative;margin:0;color:var(--shr-blue)}
.shr-memo__quote{
  position:relative;margin:24px 0 0;
  font-family:var(--shr-font-display);font-style:italic;font-size:22px;line-height:1.35;
  color:var(--shr-harbour);
}
.shr-memo__foot{
  position:relative;margin-top:40px;display:flex;justify-content:space-between;gap:12px;
  color:var(--shr-slate);
}

/* ---- 8. Statement moment ------------------------------------------------- */

.shr-statement{
  position:relative;display:flex;align-items:center;justify-content:center;
  min-height:80svh;overflow:hidden;padding:64px 24px;
}
@media (min-width:768px){ .shr-statement{padding:112px 40px} }
.shr-statement__img{position:absolute;inset:0;height:100%;width:100%;object-fit:cover}
/* 1.52.0. .68 measured 4.41:1 on the heading, the cards and the labels in
   this band at both widths. .82 clears 7:1 on the same photograph. */
.shr-statement__veil{position:absolute;inset:0;background:rgba(8,36,58,.82)}
.shr-statement__pool{
  position:absolute;inset:0;
  background:radial-gradient(55% 45% at 50% 50%,rgba(8,36,58,.55) 0%,rgba(8,36,58,0) 75%);
}
.shr-statement__inner{position:relative;max-width:700px;margin:0 auto;text-align:center}
.shr-statement__inner h2{
  margin:0;font-family:var(--shr-font-display);font-style:italic;
  font-size:clamp(3rem,18vw,5rem);color:var(--shr-ivory);
}
@media (min-width:768px){ .shr-statement__inner h2{font-size:clamp(4rem,14vw,11rem)} }
.shr-statement__inner p{
  margin:24px 0 0;font-family:var(--shr-font-sans);font-size:16px;line-height:1.7;
  color:var(--shr-ivory);
}
@media (min-width:768px){ .shr-statement__inner p{margin-top:32px} }

/* ==========================================================================
   14. HOME SECTIONS 9 TO 16
   Selected work, blueprint, recognition, certifications, testimonials, team,
   journal, contact. Ported from routes/index.tsx.
   ========================================================================== */

/* ---- 9. Selected work ---------------------------------------------------- */

.shr-work{position:relative;overflow:hidden;background-color:var(--shr-chalk);padding:64px 20px}
@media (min-width:768px){ .shr-work{padding:128px 40px} }
.shr-work__inner{max-width:1400px;margin:0 auto}
.shr-work__head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:24px}
.shr-work__head h2{
  margin:0;font-family:var(--shr-font-display);
  font-size:clamp(2.4rem,5.5vw,5rem);color:var(--shr-harbour);
}
.shr-work__all{color:var(--shr-blue);text-decoration:none}
.shr-work__all:hover{text-decoration:underline}

.shr-work__grid{margin-top:32px;display:grid;gap:48px 40px}
@media (min-width:640px){ .shr-work__grid{grid-template-columns:repeat(2,1fr)} }
@media (min-width:768px){ .shr-work__grid{margin-top:64px;gap:64px 40px} }
@media (min-width:1024px){ .shr-work__grid{grid-template-columns:repeat(3,1fr)} }
@media (min-width:1280px){ .shr-work__grid{grid-template-columns:repeat(4,1fr)} }
.shr-card[hidden]{display:none}
.shr-card__figure{display:block;overflow:hidden}
.shr-card__figure img{
  display:block;width:100%;aspect-ratio:3/2;object-fit:cover;
  transition:transform .6s ease;
}
@media (min-width:768px){ .shr-card__figure img{aspect-ratio:4/3} }
.shr-card:hover .shr-card__figure img{transform:scale(1.04)}
.shr-card__loc{margin:20px 0 0;color:var(--shr-blue)}
@media (min-width:768px){ .shr-card__loc{margin-top:24px} }
.shr-card__name{margin:12px 0 0;font-family:var(--shr-font-display);font-size:30px;color:var(--shr-harbour)}
.shr-card__desc{
  margin:12px 0 0;max-width:28rem;
  font-family:var(--shr-font-sans);font-size:14px;line-height:1.7;color:var(--shr-slate);
}
.shr-card__link{display:inline-block;margin-top:8px;color:var(--shr-blue);text-decoration:none}
@media (min-width:768px){ .shr-card__link{margin-top:20px} }
.shr-card__link:hover,.shr-card:hover .shr-card__loc{text-decoration:underline}

.shr-work__tabs{
  margin:40px -20px 0;display:flex;gap:16px;overflow-x:auto;
  scroll-snap-type:x proximity;padding:0 20px;
}
@media (min-width:768px){
  .shr-work__tabs{margin:64px 0 0;flex-wrap:wrap;gap:12px;padding:0;overflow:visible}
}
.shr-tab{
  flex-shrink:0;scroll-snap-align:start;white-space:nowrap;
  min-height:44px;padding:12px 20px;border:0;cursor:pointer;
  background:var(--shr-paper);color:var(--shr-harbour);
  transition:background-color .3s ease,color .3s ease;
}
.shr-tab:hover{background:#e6dfd0}
.shr-tab.is-active{background:var(--shr-blue);color:var(--shr-ivory)}

/* ---- 10. Blueprint -------------------------------------------------------- */

.shr-blueprint{position:relative;overflow:hidden;padding:64px 20px}
@media (min-width:768px){ .shr-blueprint{padding:160px 40px} }
.shr-blueprint__img{
  position:absolute;inset:0;height:100%;width:100%;object-fit:cover;
  filter:grayscale(1) contrast(1.25);
}
.shr-blueprint__wash{position:absolute;inset:0;background:var(--shr-blue);opacity:.72;mix-blend-mode:multiply}
.shr-blueprint__dim{position:absolute;inset:0;background:rgba(8,36,58,.2)}
.shr-blueprint__inner{position:relative;max-width:1200px;margin:0 auto;text-align:center}
.shr-blueprint__inner h2{
  margin:0;font-family:var(--shr-font-display);
  font-size:clamp(2rem,9vw,2.75rem);color:var(--shr-ivory);
}
@media (min-width:768px){ .shr-blueprint__inner h2{font-size:clamp(2.4rem,6.5vw,5.5rem)} }
.shr-blueprint__tiles{margin-top:32px;display:grid;grid-template-columns:repeat(2,1fr);gap:32px}
@media (min-width:768px){ .shr-blueprint__tiles{margin-top:80px;gap:48px} }
@media (min-width:1024px){ .shr-blueprint__tiles{grid-template-columns:repeat(4,1fr)} }
.shr-spec{display:flex;flex-direction:column;align-items:center;text-align:center}
.shr-spec__ring{
  display:flex;align-items:center;justify-content:center;
  height:56px;width:56px;border:1px solid rgba(251,250,247,.7);border-radius:999px;
  color:var(--shr-ivory);
}
@media (min-width:768px){ .shr-spec__ring{height:64px;width:64px} }
.shr-spec__ring .shr-glyph{height:28px;width:28px}
.shr-spec h3{margin:16px 0 0;font-family:var(--shr-font-display);font-size:20px;color:var(--shr-ivory)}
@media (min-width:768px){ .shr-spec h3{margin-top:24px;font-size:24px} }
.shr-spec p{margin:8px 0 0;font-size:12px;color:rgba(251,250,247,.8)}
@media (min-width:768px){ .shr-spec p{margin-top:12px;font-size:12px} }

/* ---- 11. Recognition ------------------------------------------------------ */

.shr-recognition{background-color:var(--shr-harbour);padding:64px 20px}
@media (min-width:768px){ .shr-recognition{padding:160px 40px} }
.shr-recognition__inner{max-width:1400px;margin:0 auto}
.shr-recognition__inner h2{
  margin:24px 0 0;max-width:56rem;
  font-family:var(--shr-font-display);font-size:clamp(2.2rem,9vw,3rem);color:var(--shr-ivory);
}
@media (min-width:768px){ .shr-recognition__inner h2{margin-top:32px;font-size:clamp(2.4rem,6vw,5.2rem)} }
.shr-recognition__lede{
  margin:24px 0 0;max-width:42rem;
  font-family:var(--shr-font-sans);font-size:16px;line-height:1.7;color:rgba(251,250,247,.75);
}
@media (min-width:768px){ .shr-recognition__lede{margin-top:32px} }

.shr-recognition__awards{margin-top:32px;display:grid;gap:20px}
@media (min-width:640px){ .shr-recognition__awards{grid-template-columns:repeat(2,1fr)} }
@media (min-width:768px){ .shr-recognition__awards{margin-top:64px;gap:24px} }
@media (min-width:1024px){ .shr-recognition__awards{grid-template-columns:repeat(4,1fr)} }
.shr-award{border:1px solid var(--shr-blue);padding:24px}
@media (min-width:768px){ .shr-award{padding:28px} }
.shr-award__year{margin:0;color:var(--shr-blue)}
.shr-award h3{
  margin:16px 0 0;font-family:var(--shr-font-display);font-size:22px;line-height:1.35;color:var(--shr-ivory);
}
.shr-award__body{margin:16px 0 0;color:rgba(251,250,247,.7)}
@media (min-width:768px){ .shr-award__body{margin-top:20px} }

.shr-recognition__stats{margin-top:48px;display:grid;grid-template-columns:repeat(2,1fr);gap:40px 24px}
@media (min-width:768px){ .shr-recognition__stats{margin-top:96px;gap:48px} }
@media (min-width:1024px){ .shr-recognition__stats{grid-template-columns:repeat(4,1fr)} }
.shr-stat__num{
  display:block;font-family:var(--shr-font-display);
  font-size:clamp(2.5rem,14vw,4rem);line-height:1;color:var(--shr-blue);
}
@media (min-width:768px){ .shr-stat__num{font-size:clamp(3rem,7vw,5.5rem)} }
.shr-stat p{margin:8px 0 0;font-size:12px;color:var(--shr-ivory)}
@media (min-width:768px){ .shr-stat p{margin-top:16px;font-size:12px} }

/* ---- 12. Certifications --------------------------------------------------- */

.shr-certs{background-color:var(--shr-chalk);padding:64px 20px}
@media (min-width:768px){ .shr-certs{padding:96px 40px} }
.shr-certs__grid{
  max-width:1400px;margin:0 auto;display:grid;grid-template-columns:repeat(2,1fr);gap:32px 24px;
}
@media (min-width:481px){ .shr-certs__grid{grid-template-columns:repeat(3,1fr)} }
@media (min-width:768px){ .shr-certs__grid{gap:40px} }
@media (min-width:1024px){ .shr-certs__grid{grid-template-columns:repeat(5,1fr)} }
.shr-cert{display:flex;flex-direction:column;align-items:center;text-align:center}
.shr-cert__icon{height:28px;width:28px;color:var(--shr-blue)}
@media (min-width:768px){ .shr-cert__icon{height:32px;width:32px} }
.shr-cert p{margin:12px 0 0;font-size:12px;color:var(--shr-harbour)}
@media (min-width:768px){ .shr-cert p{margin-top:16px;font-size:12px} }

/* ---- 13. Testimonials ----------------------------------------------------- */

.shr-quotes{background-color:var(--shr-chalk);padding:64px 24px}
@media (min-width:768px){ .shr-quotes{padding:160px 40px} }
.shr-quotes__inner{max-width:900px;margin:0 auto;text-align:center}
.shr-quotes__stage{position:relative;margin-top:32px;min-height:220px}
@media (min-width:768px){ .shr-quotes__stage{margin-top:48px} }
.shr-quote{
  margin:0;position:absolute;inset:0;
  opacity:0;visibility:hidden;transition:opacity .5s ease-in-out,visibility 0s linear .5s;
}
.shr-quote.is-active{opacity:1;visibility:visible;transition:opacity .5s ease-in-out,visibility 0s linear 0s}
.shr-quote blockquote{
  margin:0;font-family:var(--shr-font-display);
  font-size:clamp(1.25rem,5.5vw,1.625rem);line-height:1.4;color:var(--shr-harbour);
}
@media (min-width:768px){
  .shr-quote blockquote{font-size:clamp(1.4rem,3vw,2.4rem);line-height:1.35}
}
.shr-quote figcaption{margin:0}
.shr-quote__name{margin:24px 0 0;font-family:var(--shr-font-sans);font-size:16px;color:var(--shr-harbour)}
@media (min-width:768px){ .shr-quote__name{margin-top:32px} }
.shr-quote__loc{margin:8px 0 0;color:var(--shr-blue)}

.shr-quotes__dots{margin-top:32px;display:flex;justify-content:center}
@media (min-width:768px){ .shr-quotes__dots{display:none} }
.shr-dot{
  display:flex;align-items:center;justify-content:center;
  height:44px;width:44px;padding:0;border:0;background:none;cursor:pointer;
}
.shr-dot + .shr-dot{margin-left:-16px}
.shr-dot span{display:block;height:10px;width:10px;border-radius:999px;background:rgba(90,107,120,.3)}
.shr-dot.is-active span{background:var(--shr-blue)}

.shr-quotes__bar{display:none;margin-top:56px}
@media (min-width:768px){ .shr-quotes__bar{display:flex} }
.shr-segbar--dark .shr-segbar__seg{background-color:rgba(8,36,58,.15)}
.shr-quotes__bar .shr-segbar__seg.is-active span{transform:scaleX(1)}

/* ---- 14. Team -------------------------------------------------------------- */

.shr-team{background-color:var(--shr-harbour);padding:64px 20px}
@media (min-width:768px){ .shr-team{padding:144px 40px} }
.shr-team__inner{max-width:1400px;margin:0 auto}
.shr-team__inner h2{
  margin:32px 0 0;font-family:var(--shr-font-display);
  font-size:clamp(2.2rem,5vw,4.2rem);color:var(--shr-ivory);
}
.shr-team__grid{margin-top:40px;display:grid;gap:40px}
@media (min-width:640px){ .shr-team__grid{grid-template-columns:repeat(2,1fr)} }
@media (min-width:768px){ .shr-team__grid{margin-top:64px} }
@media (min-width:1024px){ .shr-team__grid{grid-template-columns:repeat(4,1fr)} }
.shr-member__rule{display:block;width:100%;height:1px;background:var(--shr-blue)}
.shr-member h3{margin:16px 0 0;font-family:var(--shr-font-display);font-size:26px;color:var(--shr-ivory)}
@media (min-width:768px){ .shr-member h3{margin-top:24px} }
.shr-member__role{margin:8px 0 0;color:var(--shr-blue)}
@media (min-width:768px){ .shr-member__role{margin-top:12px} }
.shr-member__cred{
  margin:16px 0 0;font-family:var(--shr-font-sans);font-size:14px;line-height:1.7;
  color:rgba(251,250,247,.75);
}
.shr-team__cta{margin-top:64px}
.shr-pill--onharbour{border-color:var(--shr-ivory);color:var(--shr-ivory)}
.shr-pill--onharbour:hover{background:var(--shr-ivory);color:var(--shr-harbour)}

/* ---- 15. Journal ----------------------------------------------------------- */

.shr-journal{background-color:var(--shr-chalk);padding:64px 20px}
@media (min-width:768px){ .shr-journal{padding:144px 40px} }
.shr-journal__inner{max-width:1400px;margin:0 auto}
.shr-journal__inner h2{
  margin:0;font-family:var(--shr-font-display);
  font-size:clamp(2.2rem,5vw,4.4rem);color:var(--shr-harbour);
}
.shr-journal__grid{margin-top:32px;display:grid;gap:40px}
@media (min-width:768px){ .shr-journal__grid{margin-top:64px;grid-template-columns:repeat(3,1fr)} }
.shr-post__figure{display:block;overflow:hidden}
.shr-post__figure img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover}
.shr-post__tag{margin:24px 0 0;color:var(--shr-blue)}
.shr-post__title{margin:12px 0 0;font-family:var(--shr-font-display);font-size:24px;line-height:1.35}
.shr-post__title a{color:var(--shr-harbour);text-decoration:none}
.shr-post__title a:hover{color:var(--shr-blue)}
.shr-post__cta{margin-top:24px}

/* ---- 16. Contact ----------------------------------------------------------- */

.shr-contact{background-color:var(--shr-paper);padding:64px 20px}
@media (min-width:768px){ .shr-contact{padding:160px 40px} }
.shr-contact__inner{max-width:1400px;margin:0 auto;display:grid;gap:40px}
@media (min-width:1024px){ .shr-contact__inner{grid-template-columns:repeat(2,1fr);gap:96px} }
.shr-contact__inner h2{
  margin:32px 0 0;font-family:var(--shr-font-display);
  font-size:clamp(2.2rem,5.2vw,4.6rem);color:var(--shr-harbour);
}
.shr-contact__lede{
  margin:32px 0 0;max-width:28rem;
  font-family:var(--shr-font-sans);font-size:16px;line-height:1.7;color:var(--shr-slate);
}
.shr-contact__addr{margin-top:48px;font-style:normal;color:var(--shr-harbour)}
.shr-contact__addr p{margin:0 0 12px}
.shr-contact__addr a{color:inherit;text-decoration:none}
.shr-contact__addr a:hover{color:var(--shr-blue)}

.shr-contact__sheet{position:relative;overflow:hidden;padding:32px}
@media (min-width:768px){ .shr-contact__sheet{padding:40px} }
.shr-contact__rules{
  position:absolute;inset:32px;pointer-events:none;
  background-image:repeating-linear-gradient(180deg,rgba(90,107,120,.16) 0 1px,transparent 1px 30px);
}
.shr-contact__label{position:relative;margin:0;color:var(--shr-blue)}
.shr-contact__sheetlede{
  position:relative;margin:24px 0 0;
  font-family:var(--shr-font-display);font-size:22px;line-height:1.4;color:var(--shr-harbour);
}
.shr-contact__actions{
  position:relative;margin-top:40px;display:flex;flex-wrap:wrap;align-items:center;gap:20px;
}
.shr-contact__call{color:var(--shr-slate);text-decoration:none}
.shr-contact__call:hover{color:var(--shr-blue)}

/* ==========================================================================
   15. ELEMENTOR INTEGRATION
   Every page after the home page is built in Elementor. These rules are what
   make an Elementor page indistinguishable from the coded front page.

   The division of labour is deliberate:
     Elementor Site Settings  carry colour, type scale, buttons and fields.
                              One kit, read by every widget, editable by the
                              client without touching code.
     This block               carries what a preset cannot reach: the page
                              masthead, section rhythm, the reading measure,
                              surface classes and the editorial layouts.

   Interior pages render on Elementor Canvas. Canvas calls wp_body_open and
   wp_footer and nothing else, so the header, contact rail, sticky bar and
   footer all print from inc/chrome.php exactly as they do on the home page,
   and no Astra container exists to fight.
   ========================================================================== */

/* Belt and braces for a page that is on the default template rather than
   Canvas. Astra is already asked for page-builder in functions.php; this stops
   any residual gutter re-introducing a 1200px box. */
.elementor-page .site-content,
.elementor-page .site-content > .ast-container,
.elementor-page .entry-content,
.elementor-page .ast-container{
  max-width:none;width:auto;padding-left:0;padding-right:0;margin-left:0;margin-right:0;
}
.elementor-page .entry-header,
.elementor-page .ast-single-post-order,
.elementor-page .page-header{display:none}

/* Elementor's legacy boxed section, in case an imported block brings one. */
.elementor-section.elementor-section-boxed > .elementor-container{max-width:1400px}

/* ---- 15.1 The page masthead -----------------------------------------------
   Not decoration. The site header opens transparent with an Ivory wordmark
   over a Deep Harbour scrim, which is correct over the home page's hero and
   invisible over Warm Chalk. Every interior page therefore opens on a dark
   masthead, and the header is legible from the first pixel. nav.js will force
   the solid header on any page that does not have one, but the masthead is
   the pattern and a page without one is a page that has missed the pattern.

   In Elementor: an outer container, full width, CSS class shr-e-masthead.
   Optional background image with a Deep Harbour overlay at 78%.
   --------------------------------------------------------------------------- */

.shr-e-masthead{
  position:relative;overflow:hidden;
  background-color:var(--shr-harbour);
  color:var(--shr-ivory);
  padding:140px 20px 64px;
}
@media (min-width:768px){ .shr-e-masthead{padding:200px 40px 112px} }
@media (min-width:1280px){ .shr-e-masthead{padding:240px 40px 144px} }

.shr-e-masthead__inner{position:relative;z-index:2;max-width:1400px;margin:0 auto}

/* Colour deliberately absent here. Every Elementor heading colour is decided
   in ONE place, section 15.17, because two places is how the eyebrow ended up
   ivory in 1.19.0. */
.shr-e-masthead h1,
.shr-e-masthead .elementor-heading-title{
  margin:0;
  font-family:var(--shr-font-display);font-weight:400;
  line-height:1.05;letter-spacing:.01em;
}
.shr-e-masthead h1{color:var(--shr-ivory)}
.shr-e-masthead .shr-e-eyebrow{color:var(--shr-blue)}
.shr-e-masthead .shr-e-lede{color:rgba(251,250,247,.75);max-width:34rem}
.shr-e-masthead .shr-e-rule{background:var(--shr-blue)}

/* Breadcrumb trail, mono, sits under the eyebrow. Links are never blue on
   Harbour: they are Ivory at 55% and go full Ivory on hover. */
.shr-e-crumbs{
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;color:rgba(251,250,247,.55);
}
.shr-e-crumbs a{color:rgba(251,250,247,.55);text-decoration:none}
.shr-e-crumbs a:hover{color:var(--shr-ivory)}

/* ---- 15.2 Section rhythm ---------------------------------------------------
   The same vertical rhythm the coded sections use, so a hand-built section and
   an Elementor section stack without a seam. Apply to an outer container.
   --------------------------------------------------------------------------- */

.shr-e-section{padding:64px 20px}
@media (min-width:768px){ .shr-e-section{padding:144px 40px} }

.shr-e-section--tight{padding:48px 20px}
@media (min-width:768px){ .shr-e-section--tight{padding:96px 40px} }

.shr-e-section--tall{padding:80px 20px}
@media (min-width:768px){ .shr-e-section--tall{padding:180px 40px} }

.shr-e-section--flush{padding-top:0}

/* Inner widths. Apply to the inner container. */
.shr-e-inner  {width:100%;max-width:1400px;margin-left:auto;margin-right:auto}
.shr-e-narrow {width:100%;max-width:1040px;margin-left:auto;margin-right:auto}
.shr-e-prose  {width:100%;max-width:var(--shr-measure-body);margin-left:auto;margin-right:auto}
.shr-e-article{width:100%;max-width:var(--shr-measure-article);margin-left:auto;margin-right:auto}

/* ---- 15.3 Surfaces ---------------------------------------------------------
   So a container steps into the palette by class rather than by colour picker,
   and a future palette change is one edit rather than forty.
   --------------------------------------------------------------------------- */

.shr-bg-chalk  {background-color:var(--shr-chalk)}
.shr-bg-paper  {background-color:var(--shr-paper)}
.shr-bg-ivory  {background-color:var(--shr-ivory)}

/* THE DARK SURFACE, AND THE LESSON IN IT.
 *
 * 1.17.0 wrote this as  .shr-bg-harbour p { color: ... }, which reads as
 * harmless and is not. A class plus a type selector scores 0-1-1, and every
 * semantic class in this stylesheet that lands on a <p> scores 0-1-0. So the
 * surface rule silently outranked .shr-e-eyebrow, .shr-e-win__year,
 * .shr-e-win__name, .shr-e-quote__role, .shr-e-person__role and
 * .shr-e-timeline__k, and every one of them rendered as body text on a dark
 * background instead of Shakespeare Blue or Ivory. The eyebrows on the About
 * page's Values and Recognition sections were losing their blue and nobody
 * had noticed.
 *
 * The fix is not to raise those six selectors one at a time, because the next
 * class added to this file would hit the same wall. The surface now sets its
 * text colour once, on itself, and lets it INHERIT. Generic element rules are
 * wrapped in :where(), which contributes zero specificity, so any element
 * carrying a design-system class wins on its own terms. The only rules left
 * at class-on-class specificity are the handful that have to reverse a
 * hard-coded Slate, and they are listed together below where they can be
 * audited.
 *
 * If a browser were ever to drop a :where() rule it does not understand, the
 * text still inherits the right colour from the container. It degrades to
 * correct rather than to invisible.
 */
.shr-bg-harbour{
  background-color:var(--shr-harbour);
  color:rgba(251,250,247,.75);
}
.shr-bg-harbour :where(h1,h2,h3,h4,h5,h6,.elementor-heading-title){color:var(--shr-ivory)}
.shr-bg-harbour :where(a){color:var(--shr-ivory)}
.shr-bg-harbour :where(a):hover{color:var(--shr-blue)}
.shr-bg-harbour .shr-e-hair{background:rgba(251,250,247,.18)}

/* The reversals: every place a design-system class hard-codes Slate or Deep
   Harbour and therefore has to be turned back on a dark surface. */
.shr-bg-harbour .shr-e-lede,
.shr-bg-harbour .shr-e-caption,
.shr-bg-harbour .shr-e-prose p,   .shr-bg-harbour .shr-e-prose li,
.shr-bg-harbour .shr-e-article p, .shr-bg-harbour .shr-e-article li{
  color:rgba(251,250,247,.75);
}
.shr-bg-harbour .shr-e-pull{color:var(--shr-ivory)}

/* ---- 15.4 Editorial type ---------------------------------------------------
   Self-contained, one class per job, because a builder should not have to
   stack three utilities to get a label right.
   --------------------------------------------------------------------------- */

.shr-e-eyebrow{
  margin:0;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;color:var(--shr-blue);
}

.shr-e-rule{display:block;width:64px;height:2px;background:var(--shr-blue);border:0}
.shr-e-hair{display:block;width:100%;height:1px;background:rgba(90,107,120,.28);border:0}

.shr-e-lede{
  font-family:var(--shr-font-sans);font-weight:300;
  font-size:19px;line-height:1.65;color:var(--shr-slate);
}
@media (min-width:768px){ .shr-e-lede{font-size:21px} }

/* Body copy inside a reading measure. Elementor's Text Editor widget prints
   plain <p>, so this catches the copy without the builder styling each block. */
.shr-e-prose p,.shr-e-article p,
.shr-e-prose li,.shr-e-article li{
  font-family:var(--shr-font-sans);font-size:17px;line-height:1.8;color:var(--shr-slate);
}
.shr-e-prose p:first-child,.shr-e-article p:first-child{margin-top:0}
.shr-e-prose p + p,.shr-e-article p + p{margin-top:24px}
.shr-e-prose h2,.shr-e-article h2{margin:56px 0 0}
.shr-e-prose h3,.shr-e-article h3{margin:48px 0 0}
.shr-e-prose h2:first-child,.shr-e-article h2:first-child,
.shr-e-prose h3:first-child,.shr-e-article h3:first-child{margin-top:0}
.shr-e-prose ul,.shr-e-article ul{margin:24px 0 0;padding-left:1.1em}
.shr-e-prose li + li,.shr-e-article li + li{margin-top:10px}

/* A pulled line, used once per long page at most. */
.shr-e-pull{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.6rem,3vw,2.4rem);line-height:1.35;color:var(--shr-harbour);
}

/* ---- 15.5 The button -------------------------------------------------------
   Elementor Site Settings > Buttons carries these values so a plain Button
   widget is already correct. These rules only cover the variants the preset
   cannot express, and square off anything a widget rounds.
   --------------------------------------------------------------------------- */

.elementor-button,
.elementor-button-link{
  border-radius:0 !important;
  transition:background-color .3s ease,color .3s ease,border-color .3s ease;
}

/* Outline variant: add shr-e-btn-outline as the button's CSS class. */
.shr-e-btn-outline .elementor-button,
.elementor-button.shr-e-btn-outline{
  background-color:transparent;border:1px solid var(--shr-blue);color:var(--shr-blue);
}
.shr-e-btn-outline .elementor-button:hover,
.elementor-button.shr-e-btn-outline:hover{background-color:var(--shr-blue);color:var(--shr-ivory)}

/* On Deep Harbour, the outline turns Ivory or it disappears. */
.shr-bg-harbour .shr-e-btn-outline .elementor-button,
.shr-e-masthead .shr-e-btn-outline .elementor-button{
  border-color:var(--shr-ivory);color:var(--shr-ivory);
}
.shr-bg-harbour .shr-e-btn-outline .elementor-button:hover,
.shr-e-masthead .shr-e-btn-outline .elementor-button:hover{
  background-color:var(--shr-ivory);color:var(--shr-harbour);
}

/* A text link that reads as a control: mono, with a rule that draws in. */
.shr-e-textlink{
  display:inline-flex;align-items:center;gap:10px;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;color:var(--shr-blue);text-decoration:none;
}
.shr-e-textlink::after{
  content:"";display:block;width:28px;height:1px;background:currentColor;
  transition:width .3s ease;
}
.shr-e-textlink:hover::after{width:48px}

/* ---- 15.6 Images -----------------------------------------------------------
   Square corners, no shadow, and the same one-shot settle the coded sections
   use. Add img-reveal as the widget's CSS class and main.js does the rest.
   --------------------------------------------------------------------------- */

.elementor-widget-image img,
.elementor-widget-theme-post-featured-image img{
  border-radius:0;box-shadow:none;display:block;
}
.shr-e-figure{display:block;overflow:hidden;line-height:0}
.shr-e-figure img{display:block;width:100%;height:auto}
.shr-e-4x3 img{aspect-ratio:4/3;object-fit:cover}
.shr-e-3x2 img{aspect-ratio:3/2;object-fit:cover}
.shr-e-3x4 img{aspect-ratio:3/4;object-fit:cover}
.shr-e-1x1 img{aspect-ratio:1/1;object-fit:cover}
.shr-e-16x9 img{aspect-ratio:16/9;object-fit:cover}

.shr-e-caption{
  margin:16px 0 0;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;color:var(--shr-slate);
}

/* ---- 15.7 Editorial two-column --------------------------------------------
   The draft never uses an even 50/50 split for copy beside an image. Applied
   to an Elementor container set to flex row.
   --------------------------------------------------------------------------- */

.shr-e-split{display:grid;gap:40px;align-items:start}
@media (min-width:1024px){
  .shr-e-split{grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:80px}
  .shr-e-split--flip{grid-template-columns:minmax(0,7fr) minmax(0,5fr)}
  .shr-e-split--even{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (min-width:1280px){ .shr-e-split{gap:112px} }
.shr-e-sticky{position:sticky;top:120px}
@media (max-width:1023px){ .shr-e-sticky{position:static;top:auto} }

/* ---- 15.8 Fact row ---------------------------------------------------------
   The stat treatment from the home page, available as plain markup so an
   Elementor HTML widget can use it without the count-up script.
   --------------------------------------------------------------------------- */

.shr-e-facts{display:grid;gap:32px}
@media (min-width:640px){ .shr-e-facts{grid-template-columns:repeat(3,1fr);gap:40px} }
.shr-e-fact{border-top:1px solid rgba(90,107,120,.28);padding-top:20px}
.shr-bg-harbour .shr-e-fact{border-top-color:rgba(251,250,247,.22)}
.shr-e-fact__n{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(2.6rem,5vw,4rem);line-height:1;color:var(--shr-harbour);
}
.shr-bg-harbour .shr-e-fact__n{color:var(--shr-ivory)}
.shr-e-fact__l{
  margin:12px 0 0;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;color:var(--shr-slate);
}
.shr-bg-harbour .shr-e-fact__l{color:rgba(251,250,247,.6)}

/* ---- 15.9 People -----------------------------------------------------------
   The About page carries the full team with bios, so unlike the home page row
   it needs a portrait, a rule, a name, a title and a paragraph, on a light
   surface by default and flipping on Deep Harbour.
   --------------------------------------------------------------------------- */

.shr-e-people{display:grid;gap:48px}
@media (min-width:640px){ .shr-e-people{grid-template-columns:repeat(2,1fr);gap:40px} }
@media (min-width:1024px){ .shr-e-people{grid-template-columns:repeat(4,1fr)} }
.shr-e-people--wide{gap:48px}
@media (min-width:1024px){ .shr-e-people--wide{grid-template-columns:repeat(3,1fr);gap:56px} }

.shr-e-person__figure{display:block;overflow:hidden;line-height:0;background:var(--shr-fill)}
.shr-e-person__figure img{display:block;width:100%;aspect-ratio:3/4;object-fit:cover}
.shr-e-person__rule{display:block;width:100%;height:1px;background:var(--shr-blue);margin-top:24px}
.shr-e-person__name{
  margin:16px 0 0;font-family:var(--shr-font-display);font-weight:400;
  font-size:26px;line-height:1.2;color:var(--shr-harbour);
}
.shr-bg-harbour .shr-e-person__name{color:var(--shr-ivory)}
.shr-e-person__role{
  margin:8px 0 0;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;color:var(--shr-blue);
}
.shr-e-person__bio{
  margin:16px 0 0;font-family:var(--shr-font-sans);font-size:14px;line-height:1.7;
  color:var(--shr-slate);
}
.shr-bg-harbour .shr-e-person__bio{color:rgba(251,250,247,.75)}

/* A member whose bio has not been supplied yet keeps the layout honest: the
   block is there, empty, rather than the card silently collapsing shorter
   than the others. Removed the moment the copy arrives. */
.shr-e-person__bio:empty{display:block;min-height:1px}

/* ---- 15.10 Timeline --------------------------------------------------------
   Thirty years of history reads as a measured list, never as cards.
   --------------------------------------------------------------------------- */

.shr-e-timeline{margin:0;padding:0;list-style:none}
.shr-e-timeline li{
  display:grid;gap:8px;
  padding:28px 0;border-top:1px solid rgba(90,107,120,.22);
}
@media (min-width:768px){
  .shr-e-timeline li{grid-template-columns:160px minmax(0,1fr);gap:40px;padding:36px 0}
}
.shr-e-timeline li:last-child{border-bottom:1px solid rgba(90,107,120,.22)}
.shr-bg-harbour .shr-e-timeline li{border-top-color:rgba(251,250,247,.18)}
.shr-bg-harbour .shr-e-timeline li:last-child{border-bottom-color:rgba(251,250,247,.18)}
.shr-e-timeline__k{
  margin:0;font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;line-height:1.5;color:var(--shr-blue);
}
.shr-e-timeline__v{
  margin:0;font-family:var(--shr-font-sans);font-size:16px;line-height:1.7;color:var(--shr-slate);
}
.shr-bg-harbour .shr-e-timeline__v{color:rgba(251,250,247,.75)}

/* ---- 15.11 Elementor widgets we do not want opinions from ------------------ */

/* Elementor's divider, icon list and toggle all ship rounded, coloured or
   shadowed by default. */
.elementor-divider-separator{border-top-color:rgba(90,107,120,.28) !important}
.shr-bg-harbour .elementor-divider-separator{border-top-color:rgba(251,250,247,.18) !important}
.elementor-icon-list-icon i,
.elementor-icon-list-icon svg{color:var(--shr-blue);fill:var(--shr-blue)}
.elementor-widget-toggle .elementor-tab-title,
.elementor-widget-accordion .elementor-tab-title{
  border-radius:0;background:transparent;
  font-family:var(--shr-font-display);font-weight:400;
}

/* Elementor's default 20px widget gap fights the rhythm above. Site Settings
   sets it to 0; this is the fallback if that value is ever reset. */
.elementor-widget:not(:last-child){margin-block-end:0}

/* Nothing on this site casts a shadow. */
.elementor-element,
.elementor-widget-container{box-shadow:none}

/* ---- 15.12 Print ------------------------------------------------------------
   The About page and the long-form pages get printed by clients. */
@media print{
  .shr-header,.shr-mobile,.shr-rail,.shr-sticky,.shr-footer,.shr-skip{display:none !important}
  .shr-e-masthead{padding:0 0 24px;background:none;color:#000}
  .shr-e-masthead h1{color:#000}
  .reveal-item{opacity:1 !important;transform:none !important}
  body{background:#fff}
}

/* ---- 15.13 Numbered sequence -----------------------------------------------
   The giant faint numeral pattern from the home page's "What we build", made
   available to Elementor. Numbers come from a CSS counter rather than an
   attribute, because custom attributes on a widget are an Elementor Pro
   feature and this build is on the free tier.

   Markup, inside one HTML widget:
     <div class="shr-e-numbered">
       <div class="shr-e-step">
         <h3>Heading</h3>
         <p>Body.</p>
       </div>
       ... repeat ...
     </div>
   --------------------------------------------------------------------------- */

.shr-e-numbered{counter-reset:shrstep;display:grid;gap:56px}
@media (min-width:768px){ .shr-e-numbered{gap:96px} }
.shr-e-numbered--tight{gap:40px}
@media (min-width:768px){ .shr-e-numbered--tight{gap:56px} }
@media (min-width:768px){
  .shr-e-numbered--two{grid-template-columns:repeat(2,minmax(0,1fr));column-gap:80px}
  .shr-e-numbered--three{grid-template-columns:repeat(3,minmax(0,1fr));column-gap:56px}
}

.shr-e-step{position:relative;counter-increment:shrstep;padding-top:28px}
.shr-e-step::before{
  /* 1.48.0: the step numeral is gone sitewide (Kathleen, 22 September).
     The hairline above each step still separates them. */
  content:none;
}
.shr-e-step::after{
  content:"";position:absolute;top:0;left:0;right:0;height:1px;
  background:rgba(90,107,120,.28);
}
.shr-bg-harbour .shr-e-step::after,
.shr-e-masthead .shr-e-step::after{background:rgba(251,250,247,.18)}

.shr-e-step h3{
  margin:24px 0 0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.7rem,3vw,2.4rem);line-height:1.2;color:var(--shr-harbour);
}
.shr-bg-harbour .shr-e-step h3{color:var(--shr-ivory)}
.shr-e-step p{
  margin:16px 0 0;max-width:34rem;
  font-family:var(--shr-font-sans);font-size:16px;line-height:1.75;color:var(--shr-slate);
}
.shr-bg-harbour .shr-e-step p{color:rgba(251,250,247,.75)}
.shr-e-step p + p{margin-top:16px}

/* The oversized ghost numeral, desktop only, on the wide single-column form. */
@media (min-width:1024px){
  .shr-e-numbered:not(.shr-e-numbered--two):not(.shr-e-numbered--three) .shr-e-step{
    padding-left:180px;
  }
  .shr-e-numbered:not(.shr-e-numbered--two):not(.shr-e-numbered--three) .shr-e-step::before{
    font-family:var(--shr-font-display);text-transform:none;letter-spacing:0;
    font-size:140px;line-height:.8;top:18px;
    color:var(--shr-slate);opacity:.14;
  }
  .shr-bg-harbour .shr-e-numbered:not(.shr-e-numbered--two):not(.shr-e-numbered--three) .shr-e-step::before{
    color:var(--shr-ivory);opacity:.12;
  }
}

/* ---- 15.14 Checklist -------------------------------------------------------
   Community involvement, certifications, anything that is a plain list of
   named things. A rule and a blue tick, never a bullet.
   --------------------------------------------------------------------------- */

.shr-e-checklist{margin:0;padding:0;list-style:none;display:grid;gap:0}
@media (min-width:640px){ .shr-e-checklist--two{grid-template-columns:repeat(2,minmax(0,1fr));column-gap:56px} }
.shr-e-checklist li{
  position:relative;padding:18px 0 18px 32px;
  border-bottom:1px solid rgba(90,107,120,.22);
  font-family:var(--shr-font-sans);font-size:16px;line-height:1.6;color:var(--shr-harbour);
}
.shr-e-checklist li::before{
  content:"";position:absolute;left:0;top:26px;
  width:14px;height:7px;border-left:1.5px solid var(--shr-blue);
  border-bottom:1.5px solid var(--shr-blue);transform:rotate(-45deg);
}
.shr-bg-harbour .shr-e-checklist li{color:var(--shr-ivory);border-bottom-color:rgba(251,250,247,.18)}

/* ---- 15.15 Marquee recognitions --------------------------------------------
   The four headline wins, typographic. No logo files, so nothing here depends
   on the association artwork being sourced first.
   --------------------------------------------------------------------------- */

.shr-e-wins{margin:0;padding:0;list-style:none;display:grid;gap:0}
.shr-e-win{
  display:grid;gap:6px;padding:28px 0;
  border-top:1px solid rgba(251,250,247,.18);
}
@media (min-width:768px){
  .shr-e-win{grid-template-columns:110px minmax(0,1fr) auto;align-items:baseline;gap:40px;padding:32px 0}
}
.shr-e-wins .shr-e-win:last-child{border-bottom:1px solid rgba(251,250,247,.18)}
.shr-e-win__year{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:30px;line-height:1;color:var(--shr-blue);
}
.shr-e-win__name{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.25rem,2.2vw,1.65rem);line-height:1.3;color:var(--shr-ivory);
}
.shr-e-win__body{
  margin:0;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;color:rgba(251,250,247,.6);white-space:nowrap;
}

/* On a light surface the same block inverts. */
.shr-bg-chalk .shr-e-win,.shr-bg-paper .shr-e-win,.shr-bg-ivory .shr-e-win{border-top-color:rgba(90,107,120,.22)}
.shr-bg-chalk .shr-e-wins .shr-e-win:last-child,
.shr-bg-paper .shr-e-wins .shr-e-win:last-child,
.shr-bg-ivory .shr-e-wins .shr-e-win:last-child{border-bottom-color:rgba(90,107,120,.22)}
.shr-bg-chalk .shr-e-win__name,.shr-bg-paper .shr-e-win__name,.shr-bg-ivory .shr-e-win__name{color:var(--shr-harbour)}
.shr-bg-chalk .shr-e-win__body,.shr-bg-paper .shr-e-win__body,.shr-bg-ivory .shr-e-win__body{color:var(--shr-slate)}

/* ---- 15.16 The quote band --------------------------------------------------
   Deep Harbour, Playfair italic, no photograph. The reference site runs this
   band over a stock Unsplash photograph of the Lions Gate Bridge, which is not
   the client's own work and does not belong on a builder's site that sells
   craftsmanship. Typography carries it instead, and nothing here waits on an
   asset.
   --------------------------------------------------------------------------- */

.shr-e-quote{position:relative;overflow:hidden}
.shr-e-quote blockquote{
  margin:0;max-width:44rem;
  font-family:var(--shr-font-display);font-weight:400;font-style:italic;
  font-size:clamp(1.5rem,3.2vw,2.6rem);line-height:1.35;color:var(--shr-ivory);
}
.shr-e-quote blockquote p{margin:0;font:inherit;color:inherit}
.shr-e-quote__mark{
  display:block;font-family:var(--shr-font-display);font-size:120px;line-height:.6;
  color:var(--shr-blue);opacity:.35;
}
.shr-e-quote__by{margin:40px 0 0;display:grid;gap:4px}
.shr-e-quote__name{
  margin:0;font-family:var(--shr-font-sans);font-size:16px;letter-spacing:.04em;color:var(--shr-ivory);
}
.shr-e-quote__role{
  margin:0;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;color:var(--shr-blue);
}


/* ---- 15.17 ELEMENTOR HEADING COLOUR, DECIDED IN ONE PLACE ------------------
   Elementor's Heading widget puts the widget's CSS classes on the OUTER div
   and paints the visible text through its own rule:

     .elementor-widget-heading .elementor-heading-title { color: var(--e-global-color-primary) }

   On this site the kit's Primary is Shakespeare Blue, so out of the box EVERY
   Elementor heading renders blue. Blue is the only accent on this site and it
   belongs on links, rules, eyebrows and active states. It is never a headline.
   That rule scores 0-2-0, so a class sitting on the wrapper, which is where
   Elementor puts it, can never win against it by inheritance. It has to be
   beaten on its own element.

   So all four cases are settled here, in cascade order, and nowhere else:
     default            Deep Harbour
     on a dark surface  Ivory
     an eyebrow         Shakespeare Blue, wherever it sits
     a caption          Slate, or a dimmed Ivory on dark
   --------------------------------------------------------------------------- */

/* 1. The default. 0-2-0, later in the file than Elementor's, so it wins the tie. */
.elementor-widget-heading .elementor-heading-title{color:var(--shr-harbour)}

/* 2. Dark surfaces. 0-3-0. */
.shr-bg-harbour .elementor-widget-heading .elementor-heading-title,
.shr-e-masthead .elementor-widget-heading .elementor-heading-title{
  color:var(--shr-ivory);
}

/* 3. The eyebrow, which is blue on every surface. 0-3-0 on dark, and last. */
.shr-e-eyebrow .elementor-heading-title,
.shr-bg-harbour .shr-e-eyebrow .elementor-heading-title,
.shr-e-masthead .shr-e-eyebrow .elementor-heading-title{
  color:var(--shr-blue);
}

/* 4. The caption. */
.shr-e-caption .elementor-heading-title{color:var(--shr-slate)}
.shr-bg-harbour .shr-e-caption .elementor-heading-title,
.shr-e-masthead .shr-e-caption .elementor-heading-title{color:rgba(251,250,247,.6)}

/* The same widget also carries the wrapper's inherited type. Elementor sets no
   font-size on a Heading widget whose tag is p or span, so the mono eyebrow
   inherits correctly, but pin it anyway rather than rely on that holding
   through an Elementor update. */
.shr-e-eyebrow .elementor-heading-title{
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;
}
.shr-e-caption .elementor-heading-title{
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;
}

/* ---- 15.18 TEAM BIOS -------------------------------------------------------
   Seven people carrying two or three paragraphs each is a page in its own
   right, and a card grid turns that into a wall of text in columns. Rows
   instead: name and title hold a fixed left column and stay with you as the
   bio scrolls, the bio runs in a reading measure beside it, a hairline
   between each.

   The reason this shape was chosen over the card grid: a person whose bio has
   not arrived yet simply has a shorter row. Rob Jorgensen's bio has been
   outstanding since 14 September, and in a card grid his card would read as
   broken. In a row it reads as a person. The portrait slot collapses to
   nothing while it is empty, so the page looks finished today and takes seven
   photographs later with no rebuild.
   --------------------------------------------------------------------------- */

.shr-e-bios{margin:0;padding:0;list-style:none}

.shr-e-bio{
  display:grid;gap:16px;padding:40px 0;
  border-top:1px solid rgba(90,107,120,.22);
}
@media (min-width:900px){
  .shr-e-bio{grid-template-columns:minmax(0,4fr) minmax(0,7fr);gap:80px;padding:56px 0}
}
.shr-e-bios .shr-e-bio:last-child{border-bottom:1px solid rgba(90,107,120,.22)}

.shr-e-bio__id{display:block}
@media (min-width:900px){ .shr-e-bio__id{position:sticky;top:120px} }

.shr-e-bio__name{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.6rem,2.6vw,2.1rem);line-height:1.2;color:var(--shr-harbour);
}
.shr-e-bio__role{
  margin:10px 0 0;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;color:var(--shr-blue);
}
.shr-e-bio__link{margin:20px 0 0}

.shr-e-bio__body p{
  margin:0;max-width:34rem;
  font-family:var(--shr-font-sans);font-size:16px;line-height:1.8;color:var(--shr-slate);
}
.shr-e-bio__body p + p{margin-top:20px}

/* The portrait slot. It takes no space at all while it is empty, so today's
   page reads as finished. Drop an <img> inside and it appears at 3:4 above the
   name with nothing else to change. */
.shr-e-bio__figure{display:block;overflow:hidden;line-height:0;margin-bottom:24px}
.shr-e-bio__figure:empty{display:none}
.shr-e-bio__figure img{display:block;width:100%;aspect-ratio:3/4;object-fit:cover}

.shr-bg-harbour .shr-e-bio{border-top-color:rgba(251,250,247,.18)}
.shr-bg-harbour .shr-e-bios .shr-e-bio:last-child{border-bottom-color:rgba(251,250,247,.18)}
.shr-bg-harbour .shr-e-bio__name{color:var(--shr-ivory)}
.shr-bg-harbour .shr-e-bio__body p{color:rgba(251,250,247,.75)}

/* ---- 15.19 THE BIG FACT ROW ------------------------------------------------
   The .shr-e-facts row at display scale, for the one place per page where a
   number should stop someone scrolling. Same markup, one extra class on the
   grid. The figure counts up through assets/js/main.js:

     <span class="shr-count" data-count="30" data-suffix="+">30+</span>

   A fact with no data-count, "A+" for instance, simply does not animate.
   --------------------------------------------------------------------------- */

.shr-e-facts--lg{gap:40px}
@media (min-width:640px){ .shr-e-facts--lg{gap:56px} }
.shr-e-facts--lg .shr-e-fact{padding-top:28px}
.shr-e-facts--lg .shr-e-fact__n{
  font-size:clamp(3.2rem,8vw,6rem);letter-spacing:-.01em;
  font-variant-numeric:tabular-nums;
}
.shr-e-facts--lg .shr-e-fact__l{margin-top:16px;font-size:.75rem}

/* Tabular figures stop the row jittering sideways while the number counts. */
.shr-count{font-variant-numeric:tabular-nums}

/* ---- 15.20 CREDENTIALS -----------------------------------------------------
   Certifications and memberships, split into two groups because they are two
   different claims: what the company is qualified to build, and who it belongs
   to.

   ONE COMPONENT, TWO STATES, on purpose. Two of the ten marks in the brief do
   not exist to be sourced at all: the BC 2-5-10 warranty is a statutory
   product with no single logo, and "CBBA" is not an organisation. The rest
   arrive on their own schedule from eight different brand pages. So a tile
   renders a logo file when there is one and a Playfair lockup of the name when
   there is not, at the same height either way. The row is finished today and
   improves one file at a time, with no rebuild and no empty boxes.

   Logos sit monochrome at rest and take their colour on hover, per section 5.5.
   Where an organisation's usage rules forbid altering its mark, add
   shr-e-cred--colour to that tile and it stays in full colour throughout.
   --------------------------------------------------------------------------- */

.shr-e-creds{display:grid;gap:36px}
@media (min-width:560px){ .shr-e-creds{grid-template-columns:repeat(2,1fr);gap:32px 36px} }
@media (min-width:900px){ .shr-e-creds{grid-template-columns:repeat(3,1fr)} }
@media (min-width:1280px){ .shr-e-creds{grid-template-columns:repeat(5,1fr);gap:32px} }

.shr-e-cred{
  display:flex;flex-direction:column;
  padding-top:24px;border-top:1px solid rgba(90,107,120,.28);
  text-decoration:none;color:inherit;
}
.shr-bg-harbour .shr-e-cred{border-top-color:rgba(251,250,247,.22)}

/* The mark slot is a fixed height so a logo tile and a text tile line up on
   the same optical baseline. Section 5.5 asks for optical sizing rather than
   uniform sizing, so each logo can be nudged with its own inline max-height
   without the row falling apart. */
.shr-e-cred__mark{
  display:flex;align-items:center;
  min-height:64px;margin-bottom:20px;
}
.shr-e-cred__mark img{
  display:block;width:auto;height:auto;max-width:100%;max-height:60px;
  filter:grayscale(1) contrast(.85) opacity(.8);
  transition:filter .35s ease;
}
.shr-e-cred:hover .shr-e-cred__mark img,
.shr-e-cred:focus-visible .shr-e-cred__mark img{filter:none}
.shr-bg-harbour .shr-e-cred__mark img{filter:grayscale(1) brightness(0) invert(1) opacity(.7)}
.shr-bg-harbour .shr-e-cred:hover .shr-e-cred__mark img{filter:none}

/* Any tile the organisation will not let us alter. */
.shr-e-cred--colour .shr-e-cred__mark img{filter:none}

/* The text state. Not a fallback: a lockup, set to hold the same weight in the
   row as a logo does. */
.shr-e-cred__word{
  display:block;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:21px;line-height:1.15;letter-spacing:.01em;
  color:var(--shr-harbour);
}
@media (min-width:1280px){ .shr-e-cred__word{font-size:20px} }
.shr-bg-harbour .shr-e-cred__word{color:var(--shr-ivory)}
.shr-e-cred:hover .shr-e-cred__word{color:var(--shr-blue)}

.shr-e-cred__kind{
  margin:0;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;color:var(--shr-slate);
}
.shr-bg-harbour .shr-e-cred__kind{color:rgba(251,250,247,.6)}
.shr-e-cred:hover .shr-e-cred__kind{color:var(--shr-blue)}

/* Group heading above each of the two grids. */
.shr-e-creds__head{
  margin:0 0 28px;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.5;color:var(--shr-blue);
}

/* Touch and reduced motion get full colour from the start: a monochrome logo
   that only resolves on hover is a desktop idea. */
@media (hover:none){
  .shr-e-cred__mark img{filter:none}
}
@media (prefers-reduced-motion:reduce){
  .shr-e-cred__mark img{filter:none;transition:none}
}

/* ---- 15.21 LINE BREAKING ---------------------------------------------------
   Two rules, whole site, and they do more for how this build reads than any
   amount of spacing.

   balance evens the lines of a short block, which stops a Playfair headline
   ending on one orphaned word. On a site where the headlines run to 76px that
   single stranded word is the most visible flaw available.

   pretty prevents an orphan on the last line of running copy and avoids
   breaking the final word of a paragraph. Both are progressive: a browser that
   does not know them wraps exactly as it does today.
   --------------------------------------------------------------------------- */

h1, h2, h3,
.entry-title,
.elementor-heading-title,
.shr-e-step h3,
.shr-e-bio__name,
.shr-e-win__name,
.shr-e-cred__word,
.shr-e-person__name,
.shr-e-pull,
.shr-e-quote blockquote{
  text-wrap:balance;
}

p, li,
.shr-e-lede,
.shr-e-prose p,
.shr-e-article p,
.shr-e-bio__body p,
.shr-e-step p{
  text-wrap:pretty;
}

/* ==========================================================================
   22. THE EDITORIAL SECTION ENGINE
   Styles for page-service.php and inc/content-sections.php.

   These pages are not Elementor. Their copy lives in post_content and the
   engine arranges it. So unlike section 15, which styles what an Elementor
   widget emits, this section styles ordinary h2, h3, p, ul and a inside
   known wrappers.

   EVERY generic element rule here is wrapped in :where() and therefore
   scores zero. That is deliberate and it is the lesson from 15.3: a rule
   like .shr-bg-harbour p scores 0-1-1 and silently outranks every semantic
   class in this file. Nothing in section 22 may ever outrank a class.
   ========================================================================== */

:root{ interpolate-size:allow-keywords; }

/* ---- 22.1 The photographic masthead ---------------------------------------
   15.1 gives the dark band. This adds the full-bleed photograph beneath it,
   with a Harbour scrim heavy enough that the Ivory wordmark in the
   transparent header is legible over any frame, and a gradient that deepens
   towards the type rather than flattening the whole image.
   --------------------------------------------------------------------------- */

.shr-s-masthead--image{ background-color:var(--shr-harbour); }

.shr-s-masthead__bg{
  position:absolute;inset:0;z-index:0;overflow:hidden;
  will-change:transform;
}
.shr-s-masthead__bg img{
  width:100%;height:100%;object-fit:cover;object-position:center 42%;
  display:block;
}
.shr-s-masthead--image::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(180deg, rgba(8,36,58,.92) 0%, rgba(8,36,58,.55) 34%, rgba(8,36,58,.86) 100%),
    linear-gradient(90deg, rgba(8,36,58,.72) 0%, rgba(8,36,58,.18) 62%);
}
/* The scrim is heavier on phones: less image is visible and the type has to
   hold against whatever crop the object-position lands on. */
@media (max-width:767px){
  .shr-s-masthead--image::after{
    background:linear-gradient(180deg, rgba(8,36,58,.93) 0%, rgba(8,36,58,.78) 45%, rgba(8,36,58,.93) 100%);
  }
}

.shr-s-masthead .shr-e-rule{ display:block;width:56px;height:2px;margin:28px 0 32px; }
.shr-s-masthead .shr-e-crumbs{ margin:0 0 4px; }
.shr-s-masthead h1{ font-size:clamp(2.6rem,7vw,4.75rem);max-width:18ch; }
.shr-s-masthead .shr-e-lede{ margin-top:32px; }
.shr-s-masthead .shr-e-lede :where(p){
  margin:0;font-size:clamp(1.0625rem,1.6vw,1.25rem);line-height:1.7;
  color:rgba(251,250,247,.75);
}

/* ---- 22.2 Section heads ----------------------------------------------------
   A numeral, a blue rule, a Playfair h2. The numeral is what makes a long
   page feel navigable rather than endless, and it is the same mono eyebrow
   the home page uses so nothing reads as a different system.
   --------------------------------------------------------------------------- */

.shr-s-head{ margin:0 0 40px; }
@media (min-width:768px){ .shr-s-head{ margin-bottom:56px; } }

.shr-s-head .shr-e-eyebrow{ margin:0; }
.shr-s-head .shr-e-rule{ display:block;width:40px;height:2px;margin:18px 0 24px;background:var(--shr-blue); }
.shr-s-head :where(h2){
  margin:0;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(2rem,4.2vw,3.5rem);line-height:1.1;letter-spacing:.01em;
  color:var(--shr-harbour);max-width:20ch;text-wrap:balance;
}
.shr-bg-harbour .shr-s-head :where(h2){ color:var(--shr-ivory); }

/* ---- 22.3 Prose inside a section ------------------------------------------
   The reading measure is 720px, per section 5.2. Everything below is
   :where() so a class always wins.
   --------------------------------------------------------------------------- */

.shr-e-prose :where(p),
.shr-e-split__copy :where(p),
.shr-s-card__body :where(p),
.shr-s-q__a :where(p){
  margin:0 0 1.35em;
  font-family:var(--shr-font-sans);font-size:17px;line-height:1.8;
  color:var(--shr-slate);
}
.shr-e-prose :where(p:last-child),
.shr-e-split__copy :where(p:last-child),
.shr-s-card__body :where(p:last-child),
.shr-s-q__a :where(p:last-child){ margin-bottom:0; }

.shr-e-prose :where(h3),
.shr-e-split__copy :where(h3){
  margin:2.4em 0 .6em;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.4rem,2.4vw,1.85rem);line-height:1.25;
  color:var(--shr-harbour);
}
.shr-bg-harbour .shr-e-prose :where(h3),
.shr-bg-harbour .shr-e-split__copy :where(h3){ color:var(--shr-ivory); }

.shr-e-prose :where(ul),
.shr-e-split__copy :where(ul){ margin:0 0 1.35em;padding-left:1.15em; }
.shr-e-prose :where(li),
.shr-e-split__copy :where(li){
  margin:0 0 .6em;
  font-family:var(--shr-font-sans);font-size:17px;line-height:1.75;
  color:var(--shr-slate);
}
.shr-e-prose :where(a),
.shr-e-split__copy :where(a),
.shr-s-q__a :where(a),
.shr-s-card__body :where(a){
  color:var(--shr-blue);text-decoration:none;
  border-bottom:1px solid rgba(0,100,180,.32);
  transition:border-color .3s ease,color .3s ease;
}
.shr-e-prose :where(a:hover),
.shr-e-split__copy :where(a:hover){ color:var(--shr-harbour);border-bottom-color:currentColor; }

.shr-s-after{ margin-top:64px; }

/* The button the placeholder resolved into. */
.shr-s-cta{ margin:2.4em 0 0; }

/* ---- 22.4 The editorial split ---------------------------------------------- */

.shr-e-split__copy{ max-width:var(--shr-measure-body); }
.shr-e-split__media{ position:relative; }
@media (min-width:1024px){
  .shr-e-split__media{ margin-top:8px; }
}

/* ---- 22.5 The statement moment ---------------------------------------------
   A short block becomes a full-height Playfair statement on Deep Harbour
   rather than a stranded paragraph. This is what stops a 494-word page
   feeling thin: the copy that is too short to be a section becomes the
   loudest thing on the page instead of the quietest.
   --------------------------------------------------------------------------- */

.shr-s-statement :where(p){
  margin:0 0 .7em;
  font-family:var(--shr-font-display);font-weight:400;font-style:normal;
  font-size:clamp(1.75rem,4.4vw,3.25rem);line-height:1.18;letter-spacing:.01em;
  color:var(--shr-ivory);max-width:24ch;text-wrap:balance;
}
.shr-s-statement :where(p:last-child){ margin-bottom:0; }
.shr-bg-chalk .shr-s-statement :where(p),
.shr-bg-paper .shr-s-statement :where(p){ color:var(--shr-harbour); }

/* ---- 22.6 Capability cards -------------------------------------------------
   Any section holding three or more h3s. Never a boxed card: a hairline, a
   name and its copy, which is the same treatment the About page's values use.
   --------------------------------------------------------------------------- */

.shr-s-cards{ display:grid;gap:48px; }
@media (min-width:768px){
  .shr-s-cards--two{ grid-template-columns:repeat(2,minmax(0,1fr));gap:56px 72px; }
}
@media (min-width:1024px){
  .shr-s-cards--three{ grid-template-columns:repeat(3,minmax(0,1fr));gap:64px 56px; }
  .shr-s-cards--two{ gap:72px 112px; }
}

.shr-s-card{ position:relative;padding-top:28px; }
.shr-s-card__rule{
  position:absolute;top:0;left:0;right:0;height:1px;
  background:rgba(90,107,120,.28);
}
.shr-bg-harbour .shr-s-card__rule{ background:rgba(251,250,247,.2); }
.shr-s-card__rule::after{
  content:"";position:absolute;top:0;left:0;width:40px;height:1px;
  background:var(--shr-blue);
}
.shr-s-card :where(h3){
  margin:0 0 16px;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.3rem,2.1vw,1.7rem);line-height:1.25;
  color:var(--shr-harbour);text-wrap:balance;
}
.shr-bg-harbour .shr-s-card :where(h3){ color:var(--shr-ivory); }
.shr-s-card__body :where(p){ font-size:16px;line-height:1.75; }
.shr-bg-harbour .shr-s-card__body :where(p){ color:rgba(251,250,247,.75); }

/* ---- 22.7 The FAQ accordion ------------------------------------------------
   Native details and summary. No JavaScript, keyboard and screen reader
   correct out of the box, and it carries FAQPage schema at step 17 without
   any markup change. The open transition uses interpolate-size, which is
   ignored by browsers that do not support it, so the fallback is an instant
   open rather than a broken one.
   --------------------------------------------------------------------------- */

.shr-s-faq{ border-top:1px solid rgba(90,107,120,.24); }
.shr-bg-harbour .shr-s-faq{ border-top-color:rgba(251,250,247,.2); }

.shr-s-q{
  border-bottom:1px solid rgba(90,107,120,.24);
  block-size:auto;overflow:hidden;
  transition:block-size .4s cubic-bezier(.22,.61,.36,1);
}
.shr-bg-harbour .shr-s-q{ border-bottom-color:rgba(251,250,247,.2); }
.shr-s-q::details-content{
  block-size:0;overflow:hidden;
  transition:block-size .4s cubic-bezier(.22,.61,.36,1),content-visibility .4s allow-discrete;
}
.shr-s-q[open]::details-content{ block-size:auto; }

.shr-s-q > summary{
  display:flex;align-items:flex-start;justify-content:space-between;gap:32px;
  padding:28px 0;cursor:pointer;list-style:none;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.125rem,1.9vw,1.4rem);line-height:1.35;
  color:var(--shr-harbour);
  transition:color .3s ease;
}
.shr-s-q > summary::-webkit-details-marker{ display:none; }
.shr-bg-harbour .shr-s-q > summary{ color:var(--shr-ivory); }
.shr-s-q > summary:hover{ color:var(--shr-blue); }
.shr-s-q > summary:focus-visible{ outline:2px solid var(--shr-blue);outline-offset:4px; }

/* The mark is a plus that becomes a minus. Drawn, never a glyph, so it is
   optically centred at every size. */
.shr-s-q__mark{
  position:relative;flex:0 0 auto;width:16px;height:16px;margin-top:.4em;
}
.shr-s-q__mark::before,
.shr-s-q__mark::after{
  content:"";position:absolute;top:50%;left:0;width:16px;height:1.5px;
  background:var(--shr-blue);transform:translateY(-50%);
  transition:transform .35s cubic-bezier(.22,.61,.36,1),opacity .35s ease;
}
.shr-s-q__mark::after{ transform:translateY(-50%) rotate(90deg); }
.shr-s-q[open] .shr-s-q__mark::after{ transform:translateY(-50%) rotate(0deg);opacity:0; }

.shr-s-q__a{ padding:0 0 32px;max-width:var(--shr-measure-body); }
.shr-bg-harbour .shr-s-q__a :where(p){ color:rgba(251,250,247,.75); }

/* ---- 22.8 The closing image strip ------------------------------------------
   Photography the sections did not consume. Better than dropping it and far
   better than padding the prose with it.
   --------------------------------------------------------------------------- */

.shr-s-strip{ display:grid;gap:16px; }
@media (min-width:768px){ .shr-s-strip{ grid-template-columns:repeat(3,minmax(0,1fr));gap:24px; } }

/* ---- 22.9 The closing call to action ---------------------------------------- */

.shr-s-cta-band .shr-e-rule{ display:block;width:40px;height:2px;margin:18px 0 28px;background:var(--shr-blue); }
.shr-s-cta-band :where(h2){
  margin:0;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(2rem,4.6vw,3.5rem);line-height:1.1;
  color:var(--shr-ivory);max-width:16ch;text-wrap:balance;
}
.shr-s-cta-band .shr-e-lede{ margin:28px 0 0;max-width:46ch; }
.shr-s-cta-band .shr-e-lede,
.shr-s-cta-band .shr-e-lede :where(p){
  font-family:var(--shr-font-sans);font-size:17px;line-height:1.8;
  color:rgba(251,250,247,.75);
}
.shr-s-cta-band__actions{
  display:flex;flex-wrap:wrap;align-items:center;gap:28px;margin:40px 0 0;
}

/* ---- 22.10 Motion and reduced motion ----------------------------------------
   reveal-item and img-reveal are already driven by assets/js/main.js, so the
   engine only has to emit the classes. This is the guard for the one case
   main.js cannot cover: a section that is open on first paint because the
   visitor arrived at a hash.
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion:reduce){
  .shr-s-masthead__bg{ transform:none !important; }
  .shr-s-q,
  .shr-s-q::details-content,
  .shr-s-q__mark::before,
  .shr-s-q__mark::after{ transition:none; }
}

/* ---- 22.11 A grouped card, and the related-links row -----------------------
   Several short blocks rendered as one carded section keep their own h2, so
   the document outline is unchanged and only the layout differs. The card
   heading style therefore has to answer to h2 as well as h3.
   --------------------------------------------------------------------------- */

.shr-s-card :where(h2){
  margin:0 0 16px;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.3rem,2.1vw,1.7rem);line-height:1.25;letter-spacing:.01em;
  color:var(--shr-harbour);text-wrap:balance;
}
.shr-bg-harbour .shr-s-card :where(h2){ color:var(--shr-ivory); }
.shr-s-card .shr-e-eyebrow{ margin:0 0 12px; }

/* A list of internal links is navigation, not a capability list. It gets the
   rule-and-arrow treatment rather than blue ticks, which would claim these
   were things the company does rather than places to read next. */
.shr-s-links{ display:grid;gap:0;margin-top:8px; }
@media (min-width:768px){ .shr-s-links{ grid-template-columns:repeat(2,minmax(0,1fr));column-gap:72px; } }

.shr-s-link{
  display:flex;align-items:center;justify-content:space-between;gap:24px;
  padding:26px 0;border-bottom:1px solid rgba(90,107,120,.24);
  text-decoration:none;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.125rem,1.8vw,1.35rem);line-height:1.3;
  color:var(--shr-harbour);
  transition:color .3s ease,padding-left .35s cubic-bezier(.22,.61,.36,1);
}
.shr-bg-harbour .shr-s-link{ color:var(--shr-ivory);border-bottom-color:rgba(251,250,247,.2); }
.shr-s-link:hover,
.shr-s-link:focus-visible{ color:var(--shr-blue);padding-left:10px; }

.shr-s-link__arrow{
  position:relative;flex:0 0 auto;width:26px;height:1px;background:var(--shr-blue);
  transition:transform .35s cubic-bezier(.22,.61,.36,1);
}
.shr-s-link__arrow::after{
  content:"";position:absolute;right:0;top:50%;width:8px;height:8px;
  border-top:1px solid var(--shr-blue);border-right:1px solid var(--shr-blue);
  transform:translateY(-50%) rotate(45deg);
}
.shr-s-link:hover .shr-s-link__arrow{ transform:translateX(6px); }

@media (prefers-reduced-motion:reduce){
  .shr-s-link,
  .shr-s-link__arrow{ transition:none; }
  .shr-s-link:hover{ padding-left:0; }
}

/* ---- 22.12 ASTRA'S CONTAINER, NEUTRALISED --------------------------------
   THE DEFECT THIS FIXES, recorded so it cannot come back.

   v1.24.0's first live test rendered /custom-home-builder/ as three columns
   side by side: the dark masthead 438px wide on the left, the body copy
   squeezed to 394px in the middle with navy on both sides, and the closing
   call to action 304px on the right, all 2,700px tall. It read as a thin card
   floating between two navy walls.

   The cause was Astra's .ast-container, which is display:flex at 922px and up
   so that #primary and #secondary sit side by side. This template prints its
   sections as direct children of that container, so they became flex items.

   functions.php already asks Astra for the page-builder content layout, and
   content-sections.php now adds the body classes directly, but neither is
   relied on here. This rule is the one that cannot fail, and it mirrors the
   block that does the same job for the home page at section 9.
   --------------------------------------------------------------------------- */

body.shr-editorial .site-content,
body.shr-editorial .site-content > .ast-container,
body.shr-editorial .ast-container,
body.shr-editorial #primary,
body.shr-editorial .content-area,
body.shr-editorial .entry-content,
body[class*="page-template-page-service"] .site-content,
body[class*="page-template-page-service"] .site-content > .ast-container,
body[class*="page-template-page-service"] .ast-container,
body[class*="page-template-page-service"] #primary,
body[class*="page-template-page-service"] .content-area,
body[class*="page-template-page-service"] .entry-content{
  display:block !important;
  float:none !important;
  width:100% !important;
  max-width:none !important;
  margin-left:0 !important;
  margin-right:0 !important;
  padding-left:0 !important;
  padding-right:0 !important;
}

/* The masthead sits under the transparent header on purpose, exactly as the
   home page hero does, so the clearance added at section 8 is removed here. */
body.shr-editorial .site-content,
body[class*="page-template-page-service"] .site-content{ padding-top:0 !important; }

/* Astra's own page furniture has no place on these pages. */
body.shr-editorial .entry-header,
body.shr-editorial .page-header,
body.shr-editorial .ast-single-post-order,
body.shr-editorial #secondary,
body[class*="page-template-page-service"] .entry-header,
body[class*="page-template-page-service"] .page-header,
body[class*="page-template-page-service"] #secondary{ display:none !important; }

/* Logged-in only: Astra's admin bar pushes the fixed header down and the
   avatar was landing on top of the header button. Found in the 1.24.0 test. */
body.admin-bar.shr-editorial #shr-header{ top:32px; }
@media (max-width:782px){ body.admin-bar.shr-editorial #shr-header{ top:46px; } }

/* ---- 22.13 FIXES FROM THE 1.24.1 LIVE TEST --------------------------------
   Every rule below answers a specific defect found on
   /custom-home-builder/ and /services/retaining-wall-systems/.
   --------------------------------------------------------------------------- */

/* A. THE BUTTON HAD NO BUTTON.
   Section 15.5 styles .elementor-button.shr-e-btn-outline, because until now
   every button on an interior page came from an Elementor widget. This
   template emits a plain anchor, so BOOK A SITE VISIT rendered as bare text.
   The selector below carries no .elementor-button requirement. */
:where(a, button).shr-e-btn-outline{
  display:inline-flex;align-items:center;justify-content:center;gap:12px;
  padding:16px 30px;border:1px solid currentColor;border-radius:0;
  font-family:var(--shr-font-mono);font-size:.75rem;font-weight:400;
  text-transform:uppercase;letter-spacing:.14em;line-height:1;
  text-decoration:none;color:var(--shr-harbour);background:transparent;
  cursor:pointer;
  transition:background-color .3s ease,color .3s ease,border-color .3s ease;
}
:where(a, button).shr-e-btn-outline:hover,
:where(a, button).shr-e-btn-outline:focus-visible{
  background:var(--shr-harbour);color:var(--shr-ivory);border-color:var(--shr-harbour);
}
.shr-bg-harbour :where(a, button).shr-e-btn-outline,
.shr-e-masthead :where(a, button).shr-e-btn-outline{ color:var(--shr-ivory); }
.shr-bg-harbour :where(a, button).shr-e-btn-outline:hover,
.shr-e-masthead :where(a, button).shr-e-btn-outline:hover{
  background:var(--shr-ivory);color:var(--shr-harbour);border-color:var(--shr-ivory);
}
/* The engine re-expresses their 2017 buttons with this class, so any inline
   colour or radius that travelled with them is overridden here. */
.shr-e-prose a.shr-e-btn-outline,
.shr-e-split__copy a.shr-e-btn-outline,
.shr-s-card__body a.shr-e-btn-outline{ border-bottom:1px solid currentColor;margin-top:8px; }

/* B. CONTRAST. Shakespeare Blue on Deep Harbour measures 2.63:1, which fails
   WCAG AA. It has been shipping on every dark band since 1.19.0 and the 1.24.1
   test is what caught it. A lifted blue reads as the same colour and measures
   5.27:1. It is used ONLY on dark surfaces; light surfaces keep #0064B4, which
   is already compliant there. */
:root{ --shr-blue-lift:#3E9BE0; }

.shr-bg-harbour .shr-e-eyebrow,
.shr-e-masthead .shr-e-eyebrow,
.shr-bg-harbour .shr-e-rule,
.shr-e-masthead .shr-e-rule,
.shr-bg-harbour .shr-s-head .shr-e-rule,
.shr-bg-harbour .shr-e-step::before,
.shr-bg-harbour .shr-s-card__rule::after,
.shr-bg-harbour .shr-s-q__mark::before,
.shr-bg-harbour .shr-s-q__mark::after,
.shr-bg-harbour .shr-s-link__arrow{ color:var(--shr-blue-lift); }

.shr-bg-harbour .shr-e-rule,
.shr-e-masthead .shr-e-rule,
.shr-bg-harbour .shr-s-card__rule::after,
.shr-bg-harbour .shr-s-q__mark::before,
.shr-bg-harbour .shr-s-q__mark::after,
.shr-bg-harbour .shr-s-link__arrow{ background:var(--shr-blue-lift); }
.shr-bg-harbour .shr-s-link__arrow::after{ border-color:var(--shr-blue-lift); }
.shr-bg-harbour .shr-s-q > summary:hover{ color:var(--shr-blue-lift); }

/* The phone number beside the closing button was 11px blue on navy. */
.shr-s-call{
  font-family:var(--shr-font-mono);font-size:.8125rem;letter-spacing:.1em;
  text-transform:uppercase;text-decoration:none;
  color:var(--shr-ivory);opacity:.82;
  border-bottom:1px solid rgba(251,250,247,.3);padding-bottom:3px;
  transition:opacity .3s ease,border-color .3s ease;
}
.shr-s-call:hover{ opacity:1;border-bottom-color:var(--shr-ivory); }

/* C. THE PARALLAX STRIP. The photograph layer was exactly the height of the
   band, so translating it up opened a hard-edged navy strip about 35px tall at
   the bottom. It is now 24% taller than the band with the overflow split
   between top and bottom. */
.shr-s-masthead__bg{ inset:-12% 0; }
.shr-s-masthead__bg img{ height:100%; }

/* D. THE MASTHEAD AND THE CLOSING BAND HAD AN EMPTY RIGHT HALF.
   Both are now two-column compositions at desktop: the headline holds the
   left, the supporting copy and actions sit at the foot of the right. No copy
   is invented to fill them; the existing copy is simply placed. */
@media (min-width:1024px){
  .shr-s-masthead .shr-e-masthead__inner{
    display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);
    column-gap:96px;align-items:end;
  }
  .shr-s-masthead .shr-e-crumbs,
  .shr-s-masthead .shr-e-rule,
  .shr-s-masthead h1{ grid-column:1; }
  .shr-s-masthead .shr-e-lede{ grid-column:2;grid-row:3;margin-top:0;padding-bottom:10px; }
}

.shr-s-cta-band__grid{ display:grid;gap:40px; }
@media (min-width:1024px){
  .shr-s-cta-band__grid{ grid-template-columns:minmax(0,6fr) minmax(0,6fr);column-gap:96px;align-items:end; }
}
.shr-s-cta-band__actions{ display:flex;flex-wrap:wrap;align-items:center;gap:28px;margin:36px 0 0; }

/* E. AN INHERITED 2560px INLINE WIDTH made the card grid 2560px wide inside a
   390px phone. The engine now strips inline sizing, and this is the guard in
   case one arrives from a source it does not parse. */
.shr-e-section :where(figure, img, iframe, video, table, embed, object){
  max-width:100% !important;height:auto;
}
.shr-e-section :where(figure){ width:auto !important;margin-left:0;margin-right:0; }
.shr-e-section :where(iframe){ width:100%;aspect-ratio:16/9; }
.shr-s-cards, .shr-s-links, .shr-e-numbered, .shr-e-split{ min-width:0; }
.shr-s-card, .shr-e-step, .shr-e-split__copy, .shr-e-split__media{ min-width:0;overflow-wrap:anywhere; }

/* F. THE CREDENTIALS BLOCK broke mid-phrase at display scale. The name is a
   lockup, not a headline: it sets at label scale and never hyphenates. */
.shr-e-cred__word{
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.05rem,1.5vw,1.35rem);line-height:1.2;letter-spacing:.01em;
  color:var(--shr-harbour);hyphens:none;text-wrap:balance;
}
.shr-bg-harbour .shr-e-cred__word{ color:var(--shr-ivory); }
.shr-e-cred__kind{
  font-family:var(--shr-font-mono);font-size:.75rem;text-transform:uppercase;
  letter-spacing:.14em;color:var(--shr-slate);
}
.shr-bg-harbour .shr-e-cred__kind{ color:var(--shr-blue-lift); }
.shr-e-creds__head{
  font-family:var(--shr-font-mono);font-size:.75rem;text-transform:uppercase;
  letter-spacing:.14em;color:var(--shr-blue);margin:56px 0 28px;
}
.shr-e-creds, .shr-e-creds li{ list-style:none; }

/* G. The section numeral must always be blue mono, on every surface. One of
   them rendered grey sans-serif in the test. */
.shr-s-head .shr-e-eyebrow,
.shr-s-card .shr-e-eyebrow{
  font-family:var(--shr-font-mono) !important;
  font-size:.75rem !important;text-transform:uppercase;letter-spacing:.14em;
  color:var(--shr-blue);
}
.shr-bg-harbour .shr-s-head .shr-e-eyebrow,
.shr-bg-harbour .shr-s-card .shr-e-eyebrow{ color:var(--shr-blue-lift); }

/* H. The side rail overlapped card text and clipped the footer address at
   1150px. It now waits for room it actually has. */
@media (max-width:1399px){
  body.shr-editorial .shr-rail,
  body[class*="page-template-page-service"] .shr-rail{ display:none !important; }
}

/* I. The back-to-top control sat on top of the mobile sticky bar. */
@media (max-width:767px){
  body.shr-editorial .ast-scroll-top,
  body.shr-editorial #ast-scroll-top,
  body[class*="page-template-page-service"] .ast-scroll-top,
  body[class*="page-template-page-service"] #ast-scroll-top{ bottom:76px !important; }
}

/* A heading set as an eyebrow is never truncated, so it has to wrap cleanly. */
.shr-s-statement + *, .shr-e-narrow > .shr-e-eyebrow{ max-width:46ch; }
.shr-e-eyebrow{ text-wrap:pretty; }

/* ---- 22.14 FIXES FROM THE 1.25.0 LIVE TEST --------------------------------- */

/* A continuation section is the same section still going. It shares its
   parent's surface and loses the top padding, so a long run of prose reads as
   one section breathing instead of three orphan bands. */
.shr-s-cont{ padding-top:0 !important; }
.shr-s-cont + .shr-s-cont{ padding-top:0 !important; }
@media (min-width:768px){
  .shr-s-cont > .shr-e-prose > :first-child{ margin-top:0; }
}
/* A hairline carries the eye between the pieces without pretending to be a
   new heading. */
.shr-s-cont .shr-e-prose::before{
  content:"";display:block;width:40px;height:1px;
  background:rgba(90,107,120,.3);margin:0 0 40px;
}
.shr-bg-harbour .shr-s-cont .shr-e-prose::before{ background:rgba(251,250,247,.22); }

/* The closing band's detail list, used when a page has no closing copy. */
.shr-s-cta-band__meta{ margin:0 0 36px;display:grid;gap:18px; }
.shr-s-cta-band__meta dt{
  font-family:var(--shr-font-mono);font-size:.75rem;text-transform:uppercase;
  letter-spacing:.14em;color:var(--shr-blue-lift);margin:0 0 6px;
}
.shr-s-cta-band__meta dd{
  margin:0;font-family:var(--shr-font-sans);font-size:16px;line-height:1.7;
  color:rgba(251,250,247,.8);
}

/* Link cards carry raw anchor text, which is often a lowercase SEO phrase.
   Set at label scale rather than display scale so it does not read as a
   headline that forgot its capitals. */
.shr-s-link{
  font-family:var(--shr-font-sans);font-weight:500;
  font-size:clamp(1rem,1.3vw,1.125rem);letter-spacing:0;
}

/* Their award and certification names, wherever they appear in body copy,
   never hyphenate and never break inside a compound like 2-5-10. */
.shr-e-prose :where(p, li),
.shr-e-split__copy :where(p, li),
.shr-s-card__body :where(p, li){ hyphens:none; }
.shr-e-cred__word, .shr-e-cred__kind{ hyphens:none;word-break:keep-all; }

/* ---- 22.15 FIXES FROM THE 1.26.0 LIVE TEST ---------------------------------- */

/* A. THE SIDE RAIL. The 1.25.0 rule named .shr-contact__rail, which does not
   exist anywhere in this theme. The class is .shr-rail, and at 1150px it was
   sitting on top of the FAQ plus marks and the link arrows. */
@media (max-width:1439px){
  body.shr-editorial .shr-rail,
  body[class*="page-template-page-service"] .shr-rail{ display:none !important; }
}

/* B. CONTINUED SECTIONS left roughly 200px of dead air in the middle of a
   sentence: the parent's bottom padding, then the continuation's own, then a
   decorative hairline nobody asked for. A continuation is the same section
   still going, so it gets no padding of its own and the section before it
   gives up its bottom padding. */
.shr-e-section:has(+ .shr-s-cont){ padding-bottom:0 !important; }
.shr-s-cont{ padding-top:0 !important; }
.shr-s-cont:has(+ .shr-s-cont){ padding-bottom:0 !important; }
.shr-s-cont .shr-e-prose::before{ display:none; }
.shr-s-cont > .shr-e-prose > :first-child{ margin-top:2.2em; }
@media (min-width:768px){ .shr-s-cont > .shr-e-prose > :first-child{ margin-top:2.6em; } }

/* C. THE MASTHEAD OVERLINE. The page's own SEO headline now sits under the
   title rather than repeating itself as section 01, which also refills the
   right half of the band that emptied when the lede moved. */
.shr-s-masthead__sub{
  margin:20px 0 0;
  font-family:var(--shr-font-display);font-weight:400;font-style:italic;
  font-size:clamp(1.15rem,2vw,1.6rem);line-height:1.3;letter-spacing:.01em;
  color:rgba(251,250,247,.86);max-width:26ch;text-wrap:balance;
}
@media (min-width:1024px){
  .shr-s-masthead .shr-s-masthead__sub{ grid-column:1;max-width:30ch; }
}

/* D. NAMES BREAKING MID-PHRASE. "2-5-10 Home / Warranty Coverage" and
   "Georgie / Awards Finalist" were breaking because the checklist went to two
   columns long before it had room for two. It now waits for 900px, and each
   item balances its own lines. */
.shr-e-checklist--two{ grid-template-columns:1fr; }
@media (min-width:900px){
  .shr-e-checklist--two{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}
.shr-e-checklist li,
.shr-e-creds .shr-e-cred__word{ text-wrap:balance;hyphens:none; }
/* A compound like 2-5-10 is one token and never breaks at its hyphens. */
.shr-e-checklist li, .shr-e-cred__word, .shr-s-card :where(h2,h3){
  overflow-wrap:normal;word-break:normal;
}

/* E. The closing band's detail list reads as an address, with its commas. */
.shr-s-cta-band__meta dd{ text-wrap:pretty; }

/* ---- 22.16 THE CLIENT'S OWN MARKS -------------------------------------------
   Replaces the credentials component removed in 1.29.0. These are the award and
   association logos that are in the page's own content, rendered at a common
   optical height, monochrome at rest and in colour on hover, per section 5.5.
   No organisation is named that the page does not name itself.
   --------------------------------------------------------------------------- */

.shr-s-marks{
  display:flex;flex-wrap:wrap;align-items:center;
  gap:40px 56px;
}
@media (min-width:768px){ .shr-s-marks{ gap:48px 72px; } }

.shr-s-mark{ display:flex;align-items:center;min-height:56px; }
.shr-s-mark__img{
  display:block;width:auto;height:auto;max-width:150px;max-height:56px;
  filter:grayscale(1) contrast(.9) opacity(.72);
  transition:filter .35s ease;
}
.shr-s-mark:hover .shr-s-mark__img{ filter:none; }
.shr-bg-harbour .shr-s-mark__img{ filter:grayscale(1) brightness(0) invert(1) opacity(.7); }
.shr-bg-harbour .shr-s-mark:hover .shr-s-mark__img{ filter:none; }
@media (hover:none){ .shr-s-mark__img{ filter:none; } }
@media (prefers-reduced-motion:reduce){ .shr-s-mark__img{ filter:none;transition:none; } }

/* The closing band with no heading still needs its two columns to sit right. */
.shr-s-cta-band__lead:not(:has(h2)) .shr-e-rule{ margin-bottom:0; }

/* ---- 22.17 FIXES FROM THE 1.29.0 LIVE TEST ---------------------------------- */

/* A. THE CLIENT'S MARKS, STYLED WHERE THEY SIT.
   1.29.0 pooled every logo and reprinted it once in a band of its own, which
   detached the bathroom page's first heading from its own logo row. The marks
   now stay in the block the client put them in. This styles them in place.
   They also rendered at 34 to 108px in grey, and the NSN award badge shrank
   from 300px to 59px and could not be read. A common optical HEIGHT fixes
   that: a wide wordmark and a square badge then read at the same weight. */

[data-shr-marks]{
  display:flex !important;flex-wrap:wrap;align-items:center;
  gap:32px 48px;margin:0 0 8px;padding:0;list-style:none;
}
/* A button directly after a marks row was starting at the row's exact bottom
   edge, with no gap at all. */
[data-shr-marks] + *{ margin-top:40px; }
@media (min-width:768px){ [data-shr-marks] + *{ margin-top:52px; } }
@media (min-width:768px){ [data-shr-marks]{ gap:40px 64px; } }
[data-shr-marks] > li,
[data-shr-marks] > *{ list-style:none;margin:0;padding:0;display:flex;align-items:center; }
[data-shr-marks]::before, [data-shr-marks] > li::before{ content:none; }

img[data-shr-mark]{
  display:block;width:auto !important;height:auto !important;
  max-height:72px;max-width:180px;
  filter:grayscale(1) contrast(.9) opacity(.72);
  transition:filter .35s ease;
}
@media (min-width:768px){ img[data-shr-mark]{ max-height:84px;max-width:210px; } }
img[data-shr-mark]:hover{ filter:none; }
/* ON A DARK SURFACE, A MARK GETS A PLATE, NOT A WHITE-OUT.
   brightness(0) invert(1) turns every pixel white, so any logo supplied on a
   solid white background came out as a blank white block. Five of the six
   marks in the bathroom page's closing band disappeared that way; only CHBA
   survived, because its file is transparent. A logo cannot be relied on to
   have an alpha channel, so the dark surface gives it a light ground to sit
   on and shows it in its own colours. */
.shr-bg-harbour [data-shr-marks],
.shr-e-masthead [data-shr-marks]{ gap:24px 28px; }
.shr-bg-harbour img[data-shr-mark],
.shr-e-masthead img[data-shr-mark]{
  filter:none;
  background:var(--shr-ivory);
  padding:14px 18px;
  max-height:60px;
  box-sizing:content-box;
}
@media (min-width:768px){
  .shr-bg-harbour img[data-shr-mark],
  .shr-e-masthead img[data-shr-mark]{ max-height:64px; }
}
@media (hover:none){ img[data-shr-mark]{ filter:none; } }
@media (prefers-reduced-motion:reduce){ img[data-shr-mark]{ filter:none;transition:none; } }

/* B. THE CLOSING BAND WITH NO HEADING led with a small label over an empty
   left column. It now leads on the phone number, which is a fact rather than
   a headline, so nothing is invented to fill the space. */
.shr-s-cta-band__phone{ margin:0; }
.shr-s-cta-band__phone a{
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(2.1rem,4.4vw,3.4rem);line-height:1.05;letter-spacing:.01em;
  color:var(--shr-ivory);text-decoration:none;white-space:nowrap;
  border-bottom:1px solid rgba(251,250,247,.28);padding-bottom:6px;
  transition:border-color .3s ease;
}
.shr-s-cta-band__phone a:hover{ border-bottom-color:var(--shr-ivory); }

/* ---- 22.18 THE BANNER HEADER ------------------------------------------------
   Their kitchen, bathroom and home renovation pages carry 1600x500 panoramic
   banners as featured images. Run full bleed behind the headline those were
   upscaled 1.7 to 2.2 times and read soft. Refusing them outright would have
   left three flat navy headers.

   So a wide, short banner is not a background at all. It sits ABOVE the dark
   band at its own aspect ratio, and the headline sits beneath it. At 1135px
   wide a 1600x500 renders 355px tall, which is its native size, so nothing is
   stretched and nothing is discarded.
   --------------------------------------------------------------------------- */

.shr-s-hero-strip{
  position:relative;overflow:hidden;
  margin:0;background:var(--shr-harbour);
  padding-top:88px;                 /* clearance for the fixed header */
}
@media (min-width:1024px){ .shr-s-hero-strip{ padding-top:108px; } }

/* Natural height on a normal window, capped against the viewport on a short
   one. Filling the strip unconditionally cut 8% off the photograph for no
   reason. Leaving it entirely uncapped put the page title BELOW THE FOLD on a
   631px laptop: 108px of navy, a 354px strip and 96px of band padding landed
   the h1 at y 673. The cap only bites on short windows. */
.shr-s-hero-strip img{
  display:block;width:100%;height:auto;
  max-height:34vh;object-fit:cover;object-position:center 48%;
}
@media (min-height:860px){
  .shr-s-hero-strip img{ max-height:none; }
}
@media (max-width:767px){
  .shr-s-hero-strip img{ aspect-ratio:3/2;object-fit:cover;max-height:none; }
}

/* The dark band under a strip has already cleared the fixed header, so it
   does not need to do it twice. */
/* Tightened so the title clears the fold. The strip has already given the page
   its opening moment; the band beneath it does not need a second one. */
.shr-s-masthead--after-strip{ padding-top:44px; }
@media (min-width:768px){ .shr-s-masthead--after-strip{ padding-top:64px; } }
@media (min-width:1280px){ .shr-s-masthead--after-strip{ padding-top:72px; } }

/* The header is transparent over the strip, exactly as it is over the home
   page hero, so the Ivory wordmark needs the same dark ground beneath it. */
.shr-s-hero-strip::before{
  content:"";position:absolute;inset:0 0 auto 0;height:180px;z-index:1;
  background:linear-gradient(180deg, rgba(8,36,58,.78) 0%, rgba(8,36,58,0) 100%);
  pointer-events:none;
}

/* A marks row runs the full inner width and lays out evenly. */
.shr-e-inner > .reveal-item > [data-shr-marks]{ justify-content:flex-start; }


/* A name that must never break across lines. Added by the engine around
   organisations the page already names. No words are added or changed. */
.shr-nobr{ white-space:nowrap; }
/* On a phone a long name may wrap rather than run off the screen: 10D found
   "Canadian Home Builders Association" 25px past a 375px screen. 1.45.0. */
@media (max-width:599px){ .shr-nobr{ white-space:normal; } }


/* ==========================================================================
   23. THE PORTFOLIO
   /portfolio/ via archive-work.php, and every /project/<slug>/ via
   taxonomy-project.php. Both read the curated term meta, never a query over
   tagged attachments the way the 2017 theme did.

   NO VIEWPORT UNITS FOR WIDTH ANYWHERE IN THIS SECTION. A full-bleed image
   built from 100vw is wider than the viewport whenever a scrollbar is present,
   which is exactly the horizontal scroll the step 16 gate forbids. The gallery
   section drops its own horizontal padding instead, so a full-bleed frame is
   simply full width, and the narrower rhythms put their padding back on
   themselves. Nothing has to be told how wide the window is.
   ========================================================================== */

/* ---- 23.1 The page shell -------------------------------------------------- */

.shr-p-main{ display:block; }

/* The gallery section carries no side padding, because .shr-p-full spans it.
   Every other rhythm re-applies its own. */
.shr-e-section.shr-p-section{ padding-left:0; padding-right:0; }

.shr-p-empty{
  font-size:clamp(1.0625rem,1.6vw,1.25rem);line-height:1.7;
  color:var(--shr-slate);margin:0 0 32px;max-width:52ch;
}

/* ---- 23.2 The editorial gallery -------------------------------------------
   Never a thumbnail grid. The rhythm is chosen per photograph in
   shr_project_gallery(): a wide landscape runs full bleed and never twice in
   a row, a portrait becomes an offset inset, everything else pairs off.
   --------------------------------------------------------------------------- */

.shr-p-gallery{
  display:flex;flex-direction:column;
  gap:clamp(40px,7vw,120px);
}

.shr-p-gallery figure{ margin:0; }
.shr-p-gallery img{ width:100%;height:auto;display:block; }

/* Full bleed. Full width of the section, which has no padding of its own. */
.shr-p-full{ width:100%; }

/* The workhorse: an offset pair, the second dropped so the eye moves. */
.shr-p-pair{
  width:100%;max-width:1400px;margin:0 auto;padding:0 20px;
  display:grid;grid-template-columns:1fr;gap:24px;
}
@media (min-width:900px){
  .shr-p-pair{ grid-template-columns:1.25fr 1fr;gap:clamp(24px,3vw,56px);align-items:start;padding:0 40px; }
  .shr-p-pair__b{ margin-top:clamp(48px,8vw,140px); }
}

/* A portrait frame, held narrow and offset. Putting one in a full-bleed slot
   letterboxes it into a stripe, which is what made the 2017 grid look cheap. */
.shr-p-inset{
  width:100%;max-width:1400px;margin:0 auto;padding:0 20px;
}
@media (min-width:900px){
  .shr-p-inset{
    width:min(46%,640px);max-width:none;
    margin-right:10%;margin-left:auto;padding:0;
  }
  /* Alternate sides so a run of portraits does not march down one edge. */
  .shr-p-inset:nth-of-type(even){ margin-left:10%;margin-right:auto; }
}

.shr-p-single{
  width:100%;max-width:1160px;margin:0 auto;padding:0 20px;
}

/* ---- 23.3 The index: the lead, then the grid ------------------------------ */

.shr-p-lead{
  display:block;text-decoration:none;color:inherit;
  max-width:1400px;margin:0 auto;padding:0 20px;
}
@media (min-width:768px){ .shr-p-lead{ padding:0 40px; } }

.shr-p-lead__body{ display:block;max-width:56ch; }
.shr-p-lead__name{
  display:block;font-family:var(--shr-font-display);
  font-size:clamp(2.1rem,5vw,3.4rem);line-height:1.08;
  color:var(--shr-harbour);margin-top:18px;
}
.shr-p-lead__copy{
  display:block;margin-top:20px;font-size:clamp(1rem,1.5vw,1.1875rem);
  line-height:1.7;color:var(--shr-slate);
}
.shr-p-lead__cue{
  display:inline-block;margin-top:28px;
  font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;color:var(--shr-blue);
  border-bottom:1px solid currentColor;padding-bottom:4px;
}

.shr-p-grid{
  display:grid;grid-template-columns:1fr;
  gap:clamp(30px,3.4vw,52px);
}
@media (min-width:700px){  .shr-p-grid{ grid-template-columns:repeat(2,1fr); } }
@media (min-width:1100px){ .shr-p-grid{ grid-template-columns:repeat(3,1fr); } }

.shr-p-card{ display:block;text-decoration:none;color:inherit; }

.shr-p-card__frame{
  display:block;overflow:hidden;aspect-ratio:4/3;
  background:var(--shr-fill);
}
.shr-p-card__frame img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .9s cubic-bezier(.2,.7,.2,1);
}
.shr-p-card:hover .shr-p-card__frame img,
.shr-p-card:focus-visible .shr-p-card__frame img{ transform:scale(1.045); }

.shr-p-card__body{
  display:block;margin-top:18px;padding-top:18px;
  border-top:1px solid var(--shr-fill);
}
.shr-p-card__name{
  display:block;font-family:var(--shr-font-display);
  font-size:clamp(1.25rem,2vw,1.55rem);line-height:1.2;
  color:var(--shr-harbour);
}
.shr-p-card__meta{
  display:block;margin-top:8px;
  font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;color:var(--shr-slate);
}

/* Keyboard focus has to be visible on a card whose whole surface is the link. */
.shr-p-card:focus-visible,
.shr-p-lead:focus-visible{
  outline:2px solid var(--shr-blue);outline-offset:6px;
}

/* Hover is an enhancement, not the affordance. Under reduced motion the card
   still responds, it just does not move. */
@media (prefers-reduced-motion:reduce){
  .shr-p-card__frame img{ transition:none; }
  .shr-p-card:hover .shr-p-card__frame img{ transform:none; }
}

/* ---- 23.4 The restrained grid, for card-tier projects ---------------------
   Roughly twenty projects have every frame locked to 600px tall by the 2016
   export settings. They still get a page, because rule 1 keeps the URL alive,
   but small tiles are an honest treatment and a full-bleed band is not.
   --------------------------------------------------------------------------- */

/* Capped, so a tile is never wider than the photograph inside it. The sources
   on these projects are around 250px; four columns across a 1400px container
   renders each at ~330px and upscales every one of them by a third. On a page
   whose whole premise is that these photographs are small, enlarging them is
   the one thing not to do. At 980px the same four columns land near 227px and
   the tile downscales instead. It also reads as a contained block rather than
   a sprawl, which is the restraint this tier is for. Found at 1.39.0. */
.shr-p-tiles{
  display:grid;grid-template-columns:repeat(2,1fr);
  gap:clamp(12px,1.6vw,24px);margin-top:40px;
  max-width:980px;margin-left:auto;margin-right:auto;
}
@media (min-width:700px){  .shr-p-tiles{ grid-template-columns:repeat(3,1fr); } }
@media (min-width:1100px){ .shr-p-tiles{ grid-template-columns:repeat(4,1fr); } }

.shr-p-tile{ margin:0;overflow:hidden;aspect-ratio:4/3;background:var(--shr-fill); }
.shr-p-tile img{ width:100%;height:100%;object-fit:cover;display:block; }

/* ---- 23.5 The archival inset ----------------------------------------------
   The after runs at reading width; the before sits over one corner as a small
   framed snapshot. At 300 to 400px an old listing photograph is sharp, and its
   lower quality reads as evidence rather than as a defect.

   The frame stacks on phones instead of overlapping, because a 44% overlay on
   a 390px screen covers the thing it is meant to be compared against.
   --------------------------------------------------------------------------- */

.shr-p-bas{
  display:flex;flex-direction:column;gap:clamp(56px,8vw,128px);margin-top:48px;
}

.shr-p-ba{ margin:0;position:relative;max-width:1160px; }
.shr-p-ba__after img{ width:100%;height:auto;display:block; }

/* On a narrow screen this STACKS. It used a fixed -56px tuck, which is a
   quarter of a 223px-tall photograph on a 390px window, and the quarter it
   covered was the bottom corner where the island and the flooring sit. A tuck
   that does not scale with the image is not a tuck, it is a crop. The overlap
   is reinstated at 900px, where there is room for it. Found at 1.39.0. */
.shr-p-ba__before{
  position:relative;margin-top:14px;margin-left:0;width:72%;max-width:340px;
  background:var(--shr-ivory);padding:10px 10px 0;
  box-shadow:0 18px 44px rgba(8,36,58,.22);
}
.shr-p-ba__before img{ width:100%;height:auto;display:block; }

.shr-p-ba__label{
  display:block;padding:10px 2px 12px;
  font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;color:var(--shr-slate);
}

@media (min-width:900px){
  .shr-p-ba__before{
    position:absolute;left:auto;right:-36px;bottom:-44px;
    margin:0;width:340px;padding:12px 12px 0;
  }
  /* Alternate the corner so a run of pairs does not stack down one edge. */
  .shr-p-ba:nth-of-type(even) .shr-p-ba__before{ right:auto;left:-36px; }
  .shr-p-ba:nth-of-type(even){ margin-left:auto; }
}

/* ---- 23.6 The build sequence (1.40.0) -------------------------------------
   One photograph per stage. On a wide screen the heading and a segmented bar
   hold still in the left rail while the stages pass on the right, and the bar
   fills stage by stage: the same segmented motif as the home hero and the
   testimonials. Below 1024px the rail is an ordinary heading and the stages
   stack, because a sticky rail on a phone is a strip of the screen lost.

   Landscapes run the full stage column. Portraits are held at 62% and
   alternate sides, for the same reason the gallery insets them: a portrait in
   a full-width slot becomes a very tall stripe.
   --------------------------------------------------------------------------- */

.shr-p-seq__grid{ display:grid;grid-template-columns:1fr;gap:40px; }

.shr-p-seq__span{
  margin:0;font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;line-height:1.5;color:var(--shr-slate);
}

.shr-p-seq__progress{ display:none; }

.shr-p-seq__list{
  list-style:none;margin:0;padding:0;
  display:flex;flex-direction:column;gap:clamp(56px,8vw,120px);
}
.shr-p-seq__stage{ margin:0;padding:0; }
.shr-p-seq__figure{ margin:0; }
.shr-p-seq__img{ overflow:hidden; }
.shr-p-seq__img img{ display:block;width:100%;height:auto; }

.shr-p-seq__stage--port .shr-p-seq__figure{ width:78%; }
.shr-p-seq__stage--port:nth-child(even) .shr-p-seq__figure{ margin-left:auto; }

.shr-p-seq__cap{
  display:grid;grid-template-columns:auto 1fr;align-items:start;
  gap:0 20px;margin-top:20px;
}
.shr-p-seq__num{
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(2.75rem,5vw,4rem);line-height:.9;
  color:var(--shr-slate);opacity:.28;
}
.shr-p-seq__meta{ display:flex;flex-direction:column;gap:8px;padding-top:6px; }
.shr-p-seq__date{
  font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;line-height:1.5;color:var(--shr-blue);
}
.shr-p-seq__title{
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.25rem,2vw,1.625rem);line-height:1.25;color:var(--shr-harbour);
  text-wrap:balance;
}

@media (min-width:1024px){
  .shr-p-seq__grid{ grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:clamp(48px,6vw,112px); }

  .shr-p-seq__rail{ position:relative; }
  .shr-p-seq__hold{ position:sticky;top:120px; }

  .shr-p-seq__progress{ display:block;margin-top:40px;max-width:320px; }
  .shr-p-seq__bar{ list-style:none;margin:0;padding:0;display:flex;gap:6px; }
  .shr-p-seq__bar li{
    position:relative;flex:1;height:3px;margin:0;padding:0;
    background:var(--shr-fill);overflow:hidden;
  }
  .shr-p-seq__bar li span{
    position:absolute;inset:0;background:var(--shr-blue);
    transform:scaleX(0);transform-origin:left;
    transition:transform .6s cubic-bezier(.22,1,.36,1);
  }
  .shr-p-seq__bar li.is-on span{ transform:scaleX(1); }
  .shr-p-seq__count{
    margin:16px 0 0;font-family:var(--shr-font-mono);
    letter-spacing:.14em;font-size:.75rem;color:var(--shr-slate);
  }
  .shr-p-seq__count span{ color:var(--shr-harbour); }

  .shr-p-seq__stage--port .shr-p-seq__figure{ width:62%; }
}

@media (prefers-reduced-motion:reduce){
  .shr-p-seq__bar li span{ transition:none; }
}
.shr-p-seq .screen-reader-text{
  position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

/* ---- 24. ENGINE FIXES FROM THE STEP 9 READ (1.41.0) ------------------------ */

/* The page's own opening h1 is now the masthead headline. Several run past
   seventy characters ("Vancouver's Trusted Custom Home Builder for Luxury,
   Design & Craftsmanship"), which at the standard size ran to five lines. A
   long headline steps down a size and widens its measure. */
.shr-s-masthead--long h1{ font-size:clamp(2.1rem,4.6vw,3.6rem);max-width:24ch;line-height:1.08; }

/* A banner or map wider than 2.2:1 shows whole instead of being cropped to
   3:2, which cut two thirds of it away. */
/* No aspect-ratio override here. WordPress gives lazy images sizes="auto",
   the browser then applies size containment, and WordPress sets a 3000x1500
   placeholder size. Overriding aspect-ratio to auto threw away the ratio the
   width and height attributes supply, so the map rendered in a 1055x1500 box
   (9C, West Vancouver). Leaving the attribute ratio alone gives 1055x251.
   Reproduced and proven in a local render. 1.43.1. */
.shr-e-natural img{ object-fit:contain;height:auto; }

/* A list item with no destination still prints, as the same row without the
   arrow and without a hover, because it is not a link. */
.shr-s-link--plain{ cursor:default; }
.shr-s-link--plain:hover{ color:inherit;padding-left:0; }

/* ---- 25. FROM THE 9B AND 8F-2 CHECKS (1.42.0) ------------------------------ */

/* Short windows. At 1150 x 631, a common laptop browser with the sidebar
   open, several headlines started in the lower third or below the fold. On
   a window under 760px tall the masthead gives back some of its padding and
   the hero strip some of its height. Tall windows are untouched. */
@media (min-width:768px) and (max-height:760px){
  .shr-e-masthead{ padding-top:152px;padding-bottom:88px; }
  .shr-s-masthead--after-strip{ padding-top:48px; }
  .shr-s-hero-strip img{ max-height:28vh; }
}

/* Image strip tiles keep their own height rather than stretching to the
   tallest tile in the row. */
.shr-s-strip{ align-items:start; }

/* Team bios. The portrait column was sticky but stretched to the full row,
   so it had no room to travel. It now takes its own height and holds while
   the biography beside it scrolls. */
@media (min-width:900px){ .shr-e-bio__id{ align-self:start; } }

/* ==========================================================================
   26. THE ENQUIRY: CONTACT PAGE, FORM, THANK-YOU (1.43.0)
   The Lovable form ported onto Gravity Forms' own markup: a paper sheet with
   a tape measure, numbered mono labels, underline fields, round radios, the
   solid pill. Scoped to the 2.5 theme wrapper so every Gravity Form on the
   site wears it, including the booking pages and the one in the journal.
   Validation is the one place a second colour appears: a deep brick, used
   for error text and the failing field's underline only, because an error
   drawn in the site's blue reads as a link.
   ========================================================================== */

:root{ --shr-error:#9e3526; }

button.shr-pill{ cursor:pointer;font:inherit;font-family:var(--shr-font-mono);font-size:.75rem;letter-spacing:.14em;text-transform:uppercase; }

/* ---- 26.1 The contact page ----------------------------------------------- */

.shr-c-grid{ display:grid;gap:56px; }
@media (min-width:1024px){
  .shr-c-grid{ grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:clamp(56px,7vw,112px);align-items:start; }
  .shr-c-details{ position:sticky;top:120px; }
}
.shr-c-details .shr-e-rule{ display:block;width:40px;height:2px;margin:18px 0 28px;background:var(--shr-blue); }
.shr-c-rest{ margin:0 0 32px;max-width:34rem;color:var(--shr-slate); }
.shr-c-address{ font-style:normal;margin:0; }
.shr-c-phone{ margin:0 0 32px; }
.shr-c-phone a{
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(2rem,3.6vw,3rem);line-height:1.05;
  color:var(--shr-harbour);text-decoration:none;
}
.shr-c-phone a:hover{ color:var(--shr-blue); }
.shr-c-list{ display:grid;grid-template-columns:auto 1fr;gap:14px 28px;margin:0 0 40px; }
.shr-c-list dt{
  margin:0;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.9;color:var(--shr-blue);
}
.shr-c-list dd{ margin:0;font-size:16px;line-height:1.7;color:var(--shr-harbour); }
.shr-c-list a{ color:inherit;text-decoration:none;border-bottom:1px solid rgba(8,36,58,.25); }
.shr-c-list a:hover{ color:var(--shr-blue);border-bottom-color:var(--shr-blue); }

.shr-c-sheetwrap{ position:relative; }
.shr-c-sheet__tape{
  position:absolute;left:-14px;top:-26px;z-index:2;width:64px;height:auto;
  color:var(--shr-slate);opacity:.4;pointer-events:none;
}
.shr-c-sheet{
  position:relative;border:1px solid rgba(90,107,120,.25);
  padding:28px 20px 32px;
  box-shadow:0 18px 50px -30px rgba(8,36,58,.5);
}
@media (min-width:768px){ .shr-c-sheet{ padding:48px 48px 44px; } }
/* A sheet laid on the desk, slightly askew, that straightens the moment you
   start writing on it. */
@media (min-width:1024px){
  .shr-c-sheet{ transform:rotate(-.7deg);transition:transform .6s cubic-bezier(.22,1,.36,1); }
  .shr-c-sheet:focus-within{ transform:none; }
}

/* The map panel is built in section 30 at the foot of this file. 1.68.0. */

/* ---- 26.2 Gravity Forms, in this design ---------------------------------- */

body .gform_wrapper.gravity-theme{ margin:0;font-family:var(--shr-font-sans);color:var(--shr-harbour); }
body .gform_wrapper.gravity-theme .gform_heading{ margin:0 0 32px; }
body .gform_wrapper.gravity-theme .gform_title{
  margin:0;font-family:var(--shr-font-mono);font-weight:400;text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;line-height:1.5;color:var(--shr-blue);
}
body .gform_wrapper.gravity-theme .gform_description{ font-size:16px;color:var(--shr-slate); }

body .gform_wrapper.gravity-theme .gform_fields{ counter-reset:shr-f;row-gap:34px; }
body .gform_wrapper.gravity-theme .gfield{ counter-increment:shr-f; }
body .gform_wrapper.gravity-theme .gfield_label,
body .gform_wrapper.gravity-theme legend.gfield_label{
  display:block;margin:0 0 4px;padding:0;
  font-family:var(--shr-font-mono);font-weight:400;text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;line-height:1.6;color:var(--shr-blue);
}
/* 1.48.0: form labels are no longer numbered. */
body .gform_wrapper.gravity-theme .gfield_label::before{ content:none; }
body .gform_wrapper.gravity-theme .gfield_required{ color:var(--shr-blue);margin-left:4px; }
body .gform_wrapper.gravity-theme .gfield_required .gfield_required_text{ font-size:.75rem; }

body .gform_wrapper.gravity-theme .gfield input[type=text],
body .gform_wrapper.gravity-theme .gfield input[type=email],
body .gform_wrapper.gravity-theme .gfield input[type=tel],
body .gform_wrapper.gravity-theme .gfield input[type=number],
body .gform_wrapper.gravity-theme .gfield input[type=url],
body .gform_wrapper.gravity-theme .gfield select,
body .gform_wrapper.gravity-theme .gfield textarea{
  width:100%;min-height:48px;margin:6px 0 0;padding:12px 0;
  border:0;border-bottom:1px solid var(--shr-slate);border-radius:0;
  background:transparent;box-shadow:none;
  font-family:var(--shr-font-sans);font-size:16px;line-height:1.5;color:var(--shr-harbour);
  transition:border-color .25s ease,box-shadow .25s ease;
}
body .gform_wrapper.gravity-theme .gfield ::placeholder{ color:rgba(90,107,120,.6);opacity:1; }
body .gform_wrapper.gravity-theme .gfield input:focus,
body .gform_wrapper.gravity-theme .gfield select:focus,
body .gform_wrapper.gravity-theme .gfield textarea:focus{
  outline:none;border-bottom-color:var(--shr-blue);box-shadow:0 1px 0 0 var(--shr-blue);
}
body .gform_wrapper.gravity-theme .gfield textarea{ height:140px;min-height:120px;resize:vertical; }
body .gform_wrapper.gravity-theme .gfield select{
  appearance:none;-webkit-appearance:none;padding-right:28px;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%230064b4' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 4px center;
}

/* Name: first and last side by side, their sub-labels small and quiet. */
body .gform_wrapper.gravity-theme .ginput_complex{ gap:20px; }
body .gform_wrapper.gravity-theme .gform-field-label--type-sub,
body .gform_wrapper.gravity-theme .ginput_complex label{
  display:block;margin-top:6px;padding:0;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.12em;
  font-size:.75rem;color:var(--shr-slate);
}

/* Radios: round, the blue dot drawn in, two columns once there is room. */
body .gform_wrapper.gravity-theme .gfield_radio{ display:grid;gap:2px 24px;margin-top:6px; }
@media (min-width:560px){ body .gform_wrapper.gravity-theme .gfield_radio{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
body .gform_wrapper.gravity-theme .gchoice{ display:flex;align-items:center;gap:12px;min-height:48px;margin:0; }
body .gform_wrapper.gravity-theme .gchoice input[type=radio],
body .gform_wrapper.gravity-theme .gchoice input[type=checkbox]{
  appearance:none;-webkit-appearance:none;flex:0 0 auto;
  width:20px;height:20px;margin:0;border:1px solid var(--shr-slate);background:transparent;
  display:grid;place-content:center;cursor:pointer;
}
/* The one round thing on the site, on purpose: a radio is a circle and a
   checkbox is a square, and people read which is which by shape. The
   sitewide square-corner rule is !important, so this has to be too. */
body .gform_wrapper.gravity-theme .gchoice input[type=radio]{ border-radius:50% !important; }
body .gform_wrapper.gravity-theme .gchoice input[type=radio]::before{
  content:"";width:10px;height:10px;border-radius:50%;background:var(--shr-blue);
  transform:scale(0);transition:transform .2s ease;
}
body .gform_wrapper.gravity-theme .gchoice input[type=checkbox]::before{
  content:"";width:10px;height:10px;background:var(--shr-blue);
  transform:scale(0);transition:transform .2s ease;
}
body .gform_wrapper.gravity-theme .gchoice input:checked{ border-color:var(--shr-blue); }
body .gform_wrapper.gravity-theme .gchoice input:checked::before{ transform:scale(1); }
body .gform_wrapper.gravity-theme .gchoice input:focus-visible{ outline:2px solid var(--shr-blue);outline-offset:3px; }
body .gform_wrapper.gravity-theme .gchoice label{
  margin:0;max-width:none;cursor:pointer;
  font-family:var(--shr-font-sans);font-size:16px;line-height:1.4;color:var(--shr-harbour);
}

/* Descriptions and the footer. */
body .gform_wrapper.gravity-theme .gfield_description:not(.validation_message){
  padding-top:8px;font-size:13px;line-height:1.6;color:var(--shr-slate);
}
body .gform_wrapper.gravity-theme .gform_footer{ margin:40px 0 0;padding:0; }
body .gform_wrapper.gravity-theme .gform_footer .shr-pill{ padding:16px 28px; }

/* Validation. */
body .gform_wrapper.gravity-theme .gform_validation_errors{
  margin:0 0 32px;padding:18px 20px;border:0;border-left:2px solid var(--shr-error);border-radius:0;
  background:rgba(251,250,247,.7);box-shadow:none;
}
body .gform_wrapper.gravity-theme .gform_validation_errors > h2,
body .gform_wrapper.gravity-theme .gform_submission_error{
  margin:0;font-family:var(--shr-font-sans);font-size:16px;font-weight:500;line-height:1.5;color:var(--shr-harbour);
}
body .gform_wrapper.gravity-theme .gform_validation_errors .gform-icon{ display:none; }
body .gform_wrapper.gravity-theme .gfield_error .gfield_label{ color:var(--shr-error); }
body .gform_wrapper.gravity-theme .gfield_error input,
body .gform_wrapper.gravity-theme .gfield_error select,
body .gform_wrapper.gravity-theme .gfield_error textarea{ border-bottom-color:var(--shr-error); }
body .gform_wrapper.gravity-theme .gfield_validation_message,
body .gform_wrapper.gravity-theme .validation_message{
  margin:8px 0 0;padding:0;border:0;background:none;
  font-size:13px;line-height:1.55;color:var(--shr-error);
}
body .gform_wrapper.gravity-theme .gfield.gfield_error{ background:none;border:0;padding:0; }

/* Sending: the fields settle back and the button says so, until the thank-you
   page takes over. */
.gform_wrapper.shr-is-sending .gform_fields{ opacity:.45;transition:opacity .4s ease; }
.gform_wrapper.shr-is-sending .gform_footer .shr-pill{ pointer-events:none; }
.gform_wrapper.shr-is-sending .gform_footer .shr-dots{ animation:shr-spin 1.2s linear infinite; }
@keyframes shr-spin{ to{ transform:rotate(360deg); } }

/* ---- 26.3 The thank-you page --------------------------------------------- */

.shr-t-band{
  min-height:100vh;min-height:100svh;display:flex;align-items:center;
  background:var(--shr-harbour);color:var(--shr-ivory);
  padding:140px 20px 96px;
}
@media (min-width:768px){ .shr-t-band{ padding:128px 40px 88px; } }
.shr-t-bar{ margin-bottom:32px; }
.shr-t-band h1{ font-size:clamp(3rem,8vw,6rem); }
.shr-t-inner{ width:100%;max-width:880px;margin:0 auto; }
.shr-t-tick{ display:block;width:64px;height:64px;color:#3e9be0; }
.shr-t-tick__ring{ stroke-dasharray:190;stroke-dashoffset:190;animation:shr-draw .9s cubic-bezier(.65,0,.35,1) .15s forwards; }
.shr-t-tick__mark{ stroke-dasharray:44;stroke-dashoffset:44;animation:shr-draw .5s cubic-bezier(.65,0,.35,1) .85s forwards; }
@keyframes shr-draw{ to{ stroke-dashoffset:0; } }
.shr-t-bar{ list-style:none;display:flex;gap:8px;width:180px;margin:32px 0 40px;padding:0; }
.shr-t-bar li{ position:relative;flex:1;height:3px;margin:0;background:rgba(251,250,247,.25);overflow:hidden; }
.shr-t-bar li span{ position:absolute;inset:0;background:#3e9be0;transform:scaleX(0);transform-origin:left;animation:shr-fill .45s ease-out forwards; }
.shr-t-bar li:nth-child(1) span{ animation-delay:1.1s; }
.shr-t-bar li:nth-child(2) span{ animation-delay:1.5s; }
.shr-t-bar li:nth-child(3) span{ animation-delay:1.9s; }
.shr-t-band h1{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(3rem,9vw,7rem);line-height:1;letter-spacing:.01em;color:var(--shr-ivory);
}
.shr-t-body{ margin-top:32px;max-width:38rem; }
.shr-t-body :where(p,h2,h3,h4){
  margin:0 0 16px;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.25rem,2.2vw,1.6rem);line-height:1.4;color:rgba(251,250,247,.86);
}
.shr-t-meta{ display:grid;grid-template-columns:auto 1fr;gap:10px 28px;margin:40px 0 0; }
.shr-t-meta dt{ margin:0;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;font-size:.75rem;line-height:1.9;color:#3e9be0; }
.shr-t-meta dd{ margin:0;font-size:16px;line-height:1.7;color:rgba(251,250,247,.8); }
.shr-t-meta a{ color:var(--shr-ivory);text-decoration:none;border-bottom:1px solid rgba(251,250,247,.3); }
.shr-t-actions{ display:flex;flex-wrap:wrap;gap:16px;margin-top:48px; }
.shr-t-actions .shr-pill--outline{ border-color:rgba(251,250,247,.6);color:var(--shr-ivory); }
.shr-t-actions .shr-pill--outline:hover{ background:var(--shr-ivory);color:var(--shr-harbour);border-color:var(--shr-ivory); }

@media (prefers-reduced-motion:reduce){
  .shr-c-sheet{ transition:none; }
  .shr-c-map__frame{ transition:none; }
  .gform_wrapper.shr-is-sending .gform_footer .shr-dots{ animation:none; }
  .shr-t-tick__ring,.shr-t-tick__mark{ animation:none;stroke-dashoffset:0; }
  .shr-t-bar li span{ animation:none;transform:scaleX(1); }
}

/* Every form field runs the full width of the sheet, as in the Lovable form.
   Gravity Forms' own layout widths are set by dragging in its editor, and
   hiding the confirm-email field at 13B left Email alone at half width.
   First and last name still sit side by side inside the Name field. 1.43.1. */
body .gform_wrapper.gravity-theme .gform_fields .gfield{ grid-column:1 / -1; }

/* A small image left where the author put it: an icon beside its list item, a
   badge in a paragraph. It keeps its own size and sits on the text line.
   1.43.1. */
.shr-e-section img[data-shr-inline]{ display:inline-block;vertical-align:middle; }
.shr-e-section li img[data-shr-inline]{ margin:0 12px 0 0; }
/* A list whose items carry their own icon needs no bullet and no tick. */
.shr-e-section li:has(> img[data-shr-inline]),
.shr-e-section li:has(> a > img[data-shr-inline]){ list-style:none; }
.shr-e-checklist li:has(img[data-shr-inline])::before{ display:none; }

/* ==========================================================================
   27. THE JOURNAL: INDEX, CARDS, ARTICLE (1.44.0)
   ========================================================================== */

/* ---- 27.1 Index ---------------------------------------------------------- */
.shr-j-lead{ display:grid;gap:40px;align-items:center; }
@media (min-width:1024px){ .shr-j-lead{ grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(48px,6vw,96px); } }
.shr-j-lead--text{ grid-template-columns:1fr; }
.shr-j-lead__figure{ display:block;overflow:hidden; }
.shr-j-lead__figure img{ display:block;width:100%;height:auto;aspect-ratio:4/3;object-fit:cover; }
.shr-j-lead__copy .shr-e-rule{ display:block;width:40px;height:2px;margin:18px 0 24px;background:var(--shr-blue); }
.shr-j-lead__copy h2{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(2rem,3.8vw,3.25rem);line-height:1.12;text-wrap:balance;
}
.shr-j-lead__copy h2 a{ color:var(--shr-harbour);text-decoration:none; }
.shr-j-lead__copy h2 a:hover{ color:var(--shr-blue); }
.shr-j-lead__excerpt{ margin:24px 0 0;max-width:34rem;font-size:16px;line-height:1.75;color:var(--shr-slate); }
.shr-j-lead__time{
  margin:20px 0 28px;font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;color:var(--shr-slate);
}

.shr-j-grid{ display:grid;gap:56px 40px; }
@media (min-width:768px){ .shr-j-grid{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (min-width:1200px){ .shr-j-grid{ grid-template-columns:repeat(3,minmax(0,1fr)); } }
.shr-j-card{ margin:0; }
.shr-j-card__figure{ display:block;overflow:hidden;margin-bottom:22px; }
.shr-j-card__figure img{ display:block;width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;transition:transform .8s cubic-bezier(.22,1,.36,1); }
.shr-j-card:hover .shr-j-card__figure img{ transform:scale(1.03); }
.shr-j-card--text{ padding-top:22px;border-top:1px solid rgba(90,107,120,.3); }
.shr-j-card__meta{
  margin:0;font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;line-height:1.6;color:var(--shr-blue);
}
.shr-j-card__title{
  margin:12px 0 0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.3rem,1.8vw,1.6rem);line-height:1.3;text-wrap:balance;
}
.shr-j-card__title a{ color:var(--shr-harbour);text-decoration:none; }
.shr-j-card__title a:hover{ color:var(--shr-blue); }
.shr-j-card__excerpt{ margin:12px 0 0;font-size:16px;line-height:1.7;color:var(--shr-slate); }

.shr-j-pages{ margin-top:72px; }
.shr-j-pages ul{ list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:10px; }
.shr-j-pages li{ margin:0; }
.shr-j-pages a,.shr-j-pages span{
  display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;padding:0 14px;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;font-size:.75rem;
  border:1px solid rgba(90,107,120,.35);color:var(--shr-harbour);text-decoration:none;
}
.shr-j-pages a:hover{ border-color:var(--shr-blue);color:var(--shr-blue); }
.shr-j-pages .current{ background:var(--shr-harbour);border-color:var(--shr-harbour);color:var(--shr-ivory); }

/* ---- 27.2 The article ---------------------------------------------------- */
.shr-j-byline{
  margin:0;font-family:var(--shr-font-mono) !important;text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem !important;color:rgba(251,250,247,.72) !important;
}
.shr-j-article{ padding-left:20px;padding-right:20px; }
.shr-j-body{
  width:100%;max-width:var(--shr-measure-article);margin:0 auto;
  font-size:18px;line-height:1.78;color:var(--shr-harbour);
}
.shr-j-body > *:first-child{ margin-top:0; }
.shr-j-body p{ margin:0 0 1.35em; }
.shr-j-body h2,.shr-j-body h3,.shr-j-body h4{
  font-family:var(--shr-font-display);font-weight:400;color:var(--shr-harbour);text-wrap:balance;
}
.shr-j-body h2{ margin:2.2em 0 .7em;font-size:clamp(1.7rem,3vw,2.2rem);line-height:1.2; }
.shr-j-body h3{ margin:1.9em 0 .6em;font-size:clamp(1.35rem,2.2vw,1.6rem);line-height:1.3; }
.shr-j-body h4{ margin:1.6em 0 .5em;font-size:1.2rem;line-height:1.35; }
/* 1.45.3: an article deeper than h4 after re-levelling keeps a readable heading. */
.shr-j-body h5,.shr-j-body h6{
  margin:1.6em 0 .5em;font-family:var(--shr-font-mono);font-weight:500;font-size:.8rem;
  letter-spacing:.14em;text-transform:uppercase;color:var(--shr-harbour);line-height:1.5;
}
.shr-j-body a{ color:var(--shr-blue);text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px; }
.shr-j-body a:hover{ color:var(--shr-harbour); }
.shr-j-body ul,.shr-j-body ol{ margin:0 0 1.35em;padding-left:1.3em; }
.shr-j-body li{ margin:0 0 .5em; }
.shr-j-body blockquote{
  margin:2em 0;padding:0 0 0 24px;border-left:2px solid var(--shr-blue);
  font-family:var(--shr-font-display);font-style:italic;font-size:1.3rem;line-height:1.5;
}
.shr-j-body img{ display:block;max-width:100%;height:auto;margin:2em auto; }
.shr-j-body figure,.shr-j-body .wp-caption{ max-width:100% !important;margin:2em 0; }
.shr-j-body figcaption,.shr-j-body .wp-caption-text{
  margin-top:10px;font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.12em;font-size:.75rem;line-height:1.6;color:var(--shr-slate);
}
@media (min-width:768px){
  .shr-j-body .alignleft{ float:left;max-width:45%;margin:.4em 28px 16px 0; }
  .shr-j-body .alignright{ float:right;max-width:45%;margin:.4em 0 16px 28px; }
}
.shr-j-body::after{ content:"";display:table;clear:both; }
.shr-j-body iframe{ display:block;width:100%;height:auto;aspect-ratio:16/9;border:0;margin:2em 0; }
.shr-j-feature{ margin:0 0 2.2em; }
.shr-j-feature img{ margin:0; }

.shr-j-neighbours__grid{ display:grid;gap:24px; }
@media (min-width:768px){ .shr-j-neighbours__grid{ grid-template-columns:1fr 1fr; } }
.shr-j-neighbour{ display:block;padding:24px 0;border-top:1px solid rgba(90,107,120,.3);text-decoration:none; }
.shr-j-neighbour--next{ text-align:right; }
.shr-j-neighbour__dir{
  display:block;font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;color:var(--shr-blue);
}
.shr-j-neighbour__title{
  display:block;margin-top:10px;font-family:var(--shr-font-display);
  font-size:1.35rem;line-height:1.3;color:var(--shr-harbour);
}
.shr-j-neighbour:hover .shr-j-neighbour__title{ color:var(--shr-blue); }

.shr-svc-link{ display:flex;justify-content:center; }

@media (prefers-reduced-motion:reduce){
  .shr-j-card__figure img{ transition:none; }
}

/* ---- 27.3 From the 14B check -------------------------------------------- */
/* Icons now sit beside their text, not above it, however the list item wraps
   them. */
.shr-e-section li:has(img[data-shr-inline]){
  list-style:none;display:flex;align-items:flex-start;gap:16px;
}
.shr-e-section li:has(img[data-shr-inline]) > br{ display:none; }
.shr-e-section li img[data-shr-inline]{ flex:0 0 auto;margin:0; }
.shr-e-section li p:has(> img[data-shr-inline]){ display:flex;align-items:flex-start;gap:16px;margin:0; }
/* Every text field the same height, the name pair included. */
body .gform_wrapper.gravity-theme .gfield input[type=text],
body .gform_wrapper.gravity-theme .gfield input[type=email],
body .gform_wrapper.gravity-theme .gfield input[type=tel],
body .gform_wrapper.gravity-theme .gfield select{ height:52px;box-sizing:border-box; }

/* ---- 27.4 List icons become numbered rows (1.44.2) ----------------------
   A list whose items carry small clip-art icons is set as the design system's
   own numbered list: a hairline between items and a mono numeral in blue, the
   pattern the home page uses for its capabilities. The icons stay in the
   markup and are not drawn. */
.shr-editorial .shr-e-section :is(ul,ol):has(> li img[data-shr-inline="icon"]){
  list-style:none;margin-left:0;padding-left:0;counter-reset:shr-icon;
}
.shr-editorial .shr-e-section li:has(img[data-shr-inline="icon"]){
  display:block;position:relative;list-style:none;
  padding:18px 0 18px 56px;border-bottom:1px solid rgba(90,107,120,.22);
  counter-increment:shr-icon;
}
.shr-editorial .shr-e-section li:has(img[data-shr-inline="icon"])::before{
  content:counter(shr-icon, decimal-leading-zero);display:block;position:absolute;left:0;top:23px;
  width:auto;height:auto;border:0;transform:none;background:none;
  font-family:var(--shr-font-mono);font-size:.75rem;line-height:1;letter-spacing:.14em;color:var(--shr-blue);
}
.shr-editorial .shr-e-section li p:has(> img[data-shr-inline="icon"]){ display:block;margin:0; }
/* A line break inside the item's words stays a line break; only the one that
   sat directly under the icon goes with it. (27.3 hid every break in these
   items, which would join two lines into one word.) */
.shr-editorial .shr-e-section li:has(img[data-shr-inline="icon"]) > br{ display:inline; }
.shr-editorial .shr-e-section img[data-shr-inline="icon"],
.shr-editorial .shr-e-section a[data-shr-iconlink],
.shr-editorial .shr-e-section li:has(img[data-shr-inline="icon"]) :is(img[data-shr-inline="icon"], a[data-shr-iconlink]) + br{ display:none; }
.shr-editorial .shr-e-section.shr-bg-harbour li:has(img[data-shr-inline="icon"]){ border-bottom-color:rgba(251,250,247,.18); }
.shr-editorial .shr-e-section.shr-bg-harbour li:has(img[data-shr-inline="icon"])::before{ color:var(--shr-blue-lift); }

/* The service page button and any button the gallery's own description
   carries, side by side. */
.shr-svc-link{ flex-wrap:wrap;gap:12px; }

/* ---- 27.5 The journal as one page (1.44.2) --------------------------------
   The lead, a row of three, then every other article as a list of titles.
   No dates. */
.shr-j-list-section .shr-s-head{ margin-bottom:28px; }
.shr-j-list{ list-style:none;margin:0;padding:0;border-top:1px solid rgba(90,107,120,.3); }
.shr-j-list li{ margin:0;border-bottom:1px solid rgba(90,107,120,.3); }
.shr-j-list a{ display:grid;gap:8px;padding:22px 0;text-decoration:none;color:var(--shr-harbour); }
@media (min-width:900px){
  .shr-j-list a{ grid-template-columns:minmax(0,1fr) auto;align-items:baseline;gap:48px; }
}
.shr-j-list__title{
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.15rem,1.6vw,1.4rem);line-height:1.35;text-wrap:balance;transition:color .3s ease;
}
.shr-j-list__meta{
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.6;color:var(--shr-slate);
}
@media (min-width:900px){ .shr-j-list__meta{ white-space:nowrap; } }
.shr-j-list a:hover .shr-j-list__title,
.shr-j-list a:focus-visible .shr-j-list__title{ color:var(--shr-blue); }
@media (prefers-reduced-motion:reduce){ .shr-j-list__title{ transition:none; } }

/* ==========================================================================
   28. STEP 12: QUESTIONS, TESTIMONIALS, AWARDS, MEDIA, SITEMAP, WHY (1.45.0)
   ========================================================================== */

/* ---- 28.0 Shared ---------------------------------------------------------- */
.shr-e-masthead .shr-l-eyebrow{ margin:0 0 14px; }
@media (min-width:1024px){ .shr-s-masthead .shr-l-eyebrow{ grid-column:1; } }
/* A title typed wholly in capitals is set in the mono face. */
.shr-l-caps h1{
  font-family:var(--shr-font-mono) !important;font-weight:400;text-transform:uppercase;
  font-size:clamp(1.35rem,2.6vw,2.1rem) !important;line-height:1.3;letter-spacing:.06em;max-width:32ch;
}
.shr-l-quote__name{
  display:block;font-family:var(--shr-font-display);font-size:1.15rem;line-height:1.3;color:var(--shr-harbour);
}
.shr-l-quote__place{
  display:block;margin-top:6px;font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;color:var(--shr-slate);
}
.shr-bg-harbour .shr-l-quote__name{ color:var(--shr-ivory); }
.shr-bg-harbour .shr-l-quote__place{ color:rgba(251,250,247,.7); }

/* ---- 28.1 Questions ------------------------------------------------------- */
.shr-l-faq__grid{ display:grid;gap:40px; }
@media (min-width:1024px){
  .shr-l-faq__grid{ grid-template-columns:minmax(0,4fr) minmax(0,8fr);column-gap:96px;align-items:start; }
  .shr-l-faq__rail{ position:sticky;top:120px; }
}
.shr-l-faq__rail .shr-e-rule{ margin:16px 0 0; }
.shr-l-faq__note{ margin:24px 0 0;max-width:30ch;font-size:16px;line-height:1.7;color:var(--shr-slate); }
.shr-l-faq__list .shr-s-q > summary{ justify-content:flex-start; }
.shr-l-faq__list .shr-s-q > summary > span:nth-child(2){ flex:1 1 auto; }
.shr-l-faq__num{
  flex:0 0 40px;padding-top:.45em;font-family:var(--shr-font-mono);font-size:.75rem;
  letter-spacing:.14em;line-height:1;color:var(--shr-blue);
}
.shr-l-faq__list .shr-s-q__a{ padding-left:72px;padding-right:48px; }
@media (max-width:599px){
  .shr-l-faq__num{ flex-basis:32px; }
  .shr-l-faq__list .shr-s-q__a{ padding-left:0;padding-right:0; }
}

/* ---- 28.2 Testimonials ---------------------------------------------------- */
.shr-l-lead-quote{ margin:0 auto;max-width:1100px; }
.shr-l-lead-quote .shr-e-rule{ margin:16px 0 40px; }
.shr-l-lead-quote blockquote{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.6rem,3.4vw,2.75rem);line-height:1.28;color:var(--shr-harbour);text-wrap:pretty;
}
.shr-l-lead-quote figcaption{ margin-top:36px; }

.shr-l-wall{ column-count:1;column-gap:56px; }
@media (min-width:768px){ .shr-l-wall{ column-count:2; } }
@media (min-width:1200px){ .shr-l-wall{ column-count:3; } }
.shr-l-wall--three{ column-count:1; }
@media (min-width:900px){ .shr-l-wall--three{ column-count:3; } }
.shr-l-quote{
  break-inside:avoid;margin:0 0 56px;padding-top:28px;border-top:1px solid rgba(90,107,120,.3);
}
.shr-l-quote blockquote{
  margin:0 0 22px;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.15rem,1.5vw,1.3rem);line-height:1.5;color:var(--shr-harbour);text-wrap:pretty;
}

.shr-l-letter{ margin-top:18px; }
.shr-l-letter > summary{
  display:inline-flex;align-items:center;gap:10px;cursor:pointer;list-style:none;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;font-size:.75rem;
  color:var(--shr-blue);
}
.shr-l-letter > summary::-webkit-details-marker{ display:none; }
.shr-l-letter > summary::after{ content:"+";font-size:.95rem;line-height:1; }
.shr-l-letter[open] > summary::after{ content:"\2212"; }
.shr-l-letter > summary:focus-visible{ outline:2px solid var(--shr-blue);outline-offset:4px; }
.shr-l-letter__body{ margin-top:16px;font-size:16px;line-height:1.75;color:var(--shr-slate); }
.shr-l-letter__body p{ margin:0 0 1em; }
.shr-l-letter__body p:last-child{ margin-bottom:0; }

/* ---- 28.3 Awards ---------------------------------------------------------- */
.shr-l-marquee .shr-e-rule{ margin:16px 0 0; }
.shr-l-marquee__grid{ display:grid;gap:40px;margin-top:48px; }
@media (min-width:768px){ .shr-l-marquee__grid{ grid-template-columns:repeat(2,minmax(0,1fr));column-gap:56px; } }
@media (min-width:1200px){ .shr-l-marquee__grid{ grid-template-columns:repeat(4,minmax(0,1fr)); } }
.shr-l-marquee__item{ padding-top:24px;border-top:1px solid rgba(90,107,120,.3); }
.shr-l-marquee__year{
  margin:0;font-family:var(--shr-font-mono);letter-spacing:.14em;font-size:.75rem;color:var(--shr-blue);
}
.shr-l-marquee__item :is(h2,h3){
  margin:14px 0 0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.3rem,1.9vw,1.6rem);line-height:1.3;color:var(--shr-harbour);text-wrap:balance;
}
.shr-l-marquee__body{
  margin:14px 0 0;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.6;color:var(--shr-slate);
}
/* The same four on a dark band (Why Shakespeare Homes). */
.shr-bg-harbour .shr-l-marquee__item{ border-top-color:rgba(251,250,247,.2); }
.shr-bg-harbour .shr-l-marquee__year{ color:var(--shr-blue-lift); }
.shr-bg-harbour .shr-l-marquee__item :is(h2,h3){ color:var(--shr-ivory); }
.shr-bg-harbour .shr-l-marquee__body{ color:rgba(251,250,247,.7); }
.shr-l-why__proof .shr-stat__num{ color:var(--shr-blue-lift); }

.shr-l-year{ display:grid;gap:8px;padding:40px 0;border-top:1px solid rgba(90,107,120,.3); }
.shr-l-year:last-child{ border-bottom:1px solid rgba(90,107,120,.3); }
@media (min-width:900px){
  .shr-l-year{ grid-template-columns:minmax(0,4fr) minmax(0,8fr);column-gap:64px;padding:56px 0; }
  .shr-l-year__num{ position:sticky;top:120px; }
}
.shr-l-year__num{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(3rem,7vw,5.5rem);line-height:1;color:var(--shr-harbour);
}
.shr-l-year__list{ list-style:none;margin:0;padding:0; }
.shr-l-award{
  display:grid;grid-template-columns:88px minmax(0,1fr);column-gap:28px;align-items:center;
  padding:22px 0;border-bottom:1px solid rgba(90,107,120,.18);
}
.shr-l-award:last-child{ border-bottom:0; }
.shr-l-award--nomark .shr-l-award__copy{ grid-column:2; }
.shr-l-award__mark{ display:flex;align-items:center;justify-content:center;height:88px; }
/* Never drawn larger than the file: the marks are 124 to 207px tall, so a
   72px cap only ever makes them smaller. */
.shr-l-award__mark img{ display:block;width:auto;height:auto;max-width:88px;max-height:72px;object-fit:contain; }
.shr-l-award__copy{ display:block; }
.shr-l-award__body{
  display:block;margin-bottom:8px;font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:.75rem;color:var(--shr-blue);
}
.shr-l-award__title{
  display:block;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.06em;
  font-size:.875rem;line-height:1.55;color:var(--shr-harbour);text-decoration:none;
}
a.shr-l-award__title:hover,
a.shr-l-award__title:focus-visible{ color:var(--shr-blue); }
a.shr-l-award__title::after{ content:" \2192";color:var(--shr-blue); }
@media (max-width:599px){
  .shr-l-award{ grid-template-columns:64px minmax(0,1fr);column-gap:18px; }
  .shr-l-award__mark{ height:64px; }
  .shr-l-award__mark img{ max-width:64px;max-height:56px; }
}

.shr-l-award-page__grid{ display:grid;gap:40px;align-items:start; }
@media (min-width:900px){ .shr-l-award-page__grid{ grid-template-columns:minmax(0,3fr) minmax(0,9fr);column-gap:80px; } }
.shr-l-award-page__grid--nomark{ grid-template-columns:1fr; }
.shr-l-award-page__mark img{ display:block;width:auto;height:auto;max-width:100%;max-height:180px; }
.shr-l-prose.shr-j-body{ margin:0;max-width:var(--shr-measure-article); }
.shr-l-back{ margin:40px 0 0; }

/* ---- 28.4 Media ------------------------------------------------------------ */
.shr-l-press-page__grid{ display:grid;gap:40px;align-items:start; }
@media (min-width:900px){ .shr-l-press-page__grid{ grid-template-columns:minmax(0,5fr) minmax(0,7fr);column-gap:80px; } }
.shr-l-press-page__grid--nocover{ grid-template-columns:1fr; }
.shr-l-press-page__cover{ margin:0; }
.shr-l-press-page__cover img{ display:block;width:auto;max-width:100%;height:auto;box-shadow:0 30px 60px -30px rgba(8,36,58,.35); }
.shr-l-press-page__actions{ display:flex;flex-wrap:wrap;gap:14px;align-items:center; }

/* ---- 28.5 Sitemap ---------------------------------------------------------- */
.shr-l-sitemap__grid{ display:grid;gap:56px; }
@media (min-width:900px){ .shr-l-sitemap__grid{ grid-template-columns:repeat(3,minmax(0,1fr));column-gap:56px; } }
.shr-l-sitemap__col .shr-e-rule{ margin:14px 0 0; }
.shr-l-sitemap__col h2{
  margin:24px 0 20px;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.6rem,2.4vw,2rem);color:var(--shr-harbour);
}
.shr-l-map{ list-style:none;margin:0;padding:0; }
.shr-l-map li{ margin:0; }
.shr-l-map a{
  display:block;padding:9px 0;border-bottom:1px solid rgba(90,107,120,.16);
  font-size:16px;line-height:1.5;color:var(--shr-harbour);text-decoration:none;
}
.shr-l-map a:hover,.shr-l-map a:focus-visible{ color:var(--shr-blue); }
.shr-l-map ul{ list-style:none;margin:0;padding:0 0 0 18px; }
.shr-l-map ul a{ font-size:14px;color:var(--shr-slate); }
.shr-l-map--after{ margin-top:28px; }

/* ---- 28.6 Why Shakespeare Homes -------------------------------------------- */
.shr-l-why__open-grid{ display:grid;gap:48px;align-items:start; }
@media (min-width:1024px){ .shr-l-why__open-grid{ grid-template-columns:minmax(0,7fr) minmax(0,5fr);column-gap:96px; } }
.shr-l-why__quote{ margin:0; }
.shr-l-why__quote p{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.5rem,2.8vw,2.3rem);line-height:1.32;color:var(--shr-harbour);text-wrap:pretty;
}
.shr-l-why__quote footer{ margin-top:32px; }
.shr-l-why__copy p{ margin:0 0 1.2em;font-size:17px;line-height:1.8;color:var(--shr-slate); }
.shr-l-why__pillars{ padding-top:64px; }
.shr-pillar h2{
  margin:20px 0 0;font-family:var(--shr-font-display);font-weight:400;font-size:32px;color:var(--shr-harbour);
}
@media (min-width:768px){ .shr-pillar h2{ margin-top:32px;font-size:36px; } }
.shr-l-why__stats{ margin-top:40px; }
.shr-l-why__proof .shr-l-marquee__grid{ margin-top:72px; }
.shr-l-why__more{ margin:48px 0 0; }
.shr-l-why__proof .shr-pill--outline{ border-color:rgba(251,250,247,.6);color:var(--shr-ivory); }
.shr-l-why__proof .shr-pill--outline:hover{ background:var(--shr-ivory);color:var(--shr-harbour);border-color:var(--shr-ivory); }
.shr-l-why__links{ display:flex;flex-wrap:wrap;gap:14px;margin:24px 0 0; }

/* ==========================================================================
   29. NEVER ENLARGED (1.45.1, from S1)
   A photograph is drawn no wider than its own file. The gallery figures carry
   the file's width as --shr-max; a slot wider than the photograph leaves calm
   space around it rather than stretching it. S1 found frames of 400 to 900px
   drawn at 1008 to 1120px.
   ========================================================================== */
.shr-p-gallery figure[style*="--shr-max"] img{ max-width:min(100%,var(--shr-max)) !important;margin-left:auto;margin-right:auto; }
/* The portrait inset had quietly become full width: the guard at 22.x E sets
   every figure in a section to width:auto !important, which outranked the
   inset's own width, so a 445px portrait filled a 1120px column (S1). The
   inset takes its width back here, capped at the photograph's own. */
@media (min-width:900px){
  .shr-e-section .shr-p-gallery .shr-p-inset{ width:min(46%,640px) !important;margin-right:10% !important;margin-left:auto !important; }
  .shr-e-section .shr-p-gallery .shr-p-inset:nth-of-type(even){ margin-left:10% !important;margin-right:auto !important; }
  .shr-e-section .shr-p-gallery .shr-p-inset[style*="--shr-max"]{ width:min(46%,640px,var(--shr-max)) !important; }
  .shr-p-pair__a[style*="--shr-max"] img{ margin-right:0; }
  .shr-p-pair__b[style*="--shr-max"] img{ margin-left:0; }
}
.shr-p-ba[style*="--shr-max"]{ width:100%;max-width:min(1160px,var(--shr-max)) !important; }
/* An article's picture keeps the size its file can carry, whatever width the
   editor typed (1.45.1: a 500px file carried width="800"). */
.shr-j-body img[data-shr-natural]{ max-width:min(100%,var(--shr-max)) !important; }
/* Marks inside an article: a row, never stacked one per line. */
.shr-j-body img[data-shr-mark]{ display:inline-block;margin:0 28px 16px 0;vertical-align:middle; }
.shr-j-body [data-shr-marks] img[data-shr-mark]{ margin:0; }
.shr-j-body [data-shr-marks]{ margin:2em 0; }
.shr-j-body [data-shr-marks] > br{ display:none; }
/* Engine section photographs, capped at their own files (1.45.2, from 12B). */
.shr-e-section img[data-shr-natural]{ max-width:min(100%,var(--shr-max)) !important;margin-left:auto;margin-right:auto; }
/* A heading with nothing beneath it opens the next section as a label. */
.shr-s-kicker{
  margin:0 0 18px;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.6;color:var(--shr-blue);
}
.shr-bg-harbour .shr-s-kicker{ color:var(--shr-blue-lift); }

/* 1.45.7: a project's own write-up, before its photographs. */
.shr-p-story__grid{ display:grid;gap:20px; }
@media (min-width:900px){ .shr-p-story__grid{ grid-template-columns:minmax(0,1fr) minmax(0,2fr);gap:64px;align-items:start; } }
.shr-p-story__body{ max-width:var(--shr-measure-body); }
.shr-p-story__body p{ margin:0 0 1.2em;font-size:18px;line-height:1.75;color:var(--shr-harbour); }
.shr-p-story__body > p:first-child{ font-family:var(--shr-font-display);font-size:clamp(1.3rem,2vw,1.55rem);line-height:1.5; }
/* 1.45.9: the write-up's feature list, and its project details. */
.shr-p-story__features{ list-style:none;margin:1.6em 0;padding:0;display:grid;gap:0 32px;border-top:1px solid var(--shr-fill); }
@media (min-width:700px){ .shr-p-story__features{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
.shr-p-story__features li{ position:relative;margin:0;padding:12px 0 12px 22px;border-bottom:1px solid var(--shr-fill);font-size:16px;line-height:1.5;color:var(--shr-harbour); }
.shr-p-story__features li::before{ content:"";position:absolute;left:0;top:22px;width:10px;height:1px;background:var(--shr-blue); }
.shr-p-story__specs{ margin:1.6em 0;display:grid;gap:16px 32px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr)); }
.shr-p-story__specs div{ border-top:1px solid var(--shr-fill);padding-top:10px; }
.shr-p-story__specs dt{ font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;font-size:.75rem;color:var(--shr-slate); }
.shr-p-story__specs dd{ margin:4px 0 0;font-size:16px;color:var(--shr-harbour); }
.shr-p-story__body p:last-child{ margin-bottom:0; }

/* 1.45.9: the services index alternates its photographs left and right. */
@media (min-width:1024px){
  .shr-l-service-row .shr-e-split--flip .shr-e-split__media{ order:-1; }
}
.shr-l-service-row__more{ margin-top:28px; }

/* 1.46.1: the not-found page's ways in. */
.shr-l-404__ways{ display:flex;flex-wrap:wrap;gap:12px; }

/* 1.46.2, from 17A: a form page's own words in the dark band. Its headings
   were drawn in Deep Harbour on Deep Harbour; they take the band's ivory and
   the display face. Its photograph sits beside the form instead. */
.shr-s-masthead .shr-e-lede > :first-child{ margin-top:0; }
.shr-s-masthead .shr-e-lede :is(h2,h3,h4,h5,h6){
  margin:1.5em 0 .55em;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.3rem,2vw,1.6rem);line-height:1.25;letter-spacing:.01em;color:var(--shr-ivory);
}
.shr-s-masthead .shr-e-lede :where(p + p){ margin-top:1em; }
.shr-s-masthead .shr-e-lede :is(ul,ol){ margin:1em 0 0;padding-left:1.2em; }
.shr-s-masthead .shr-e-lede li{ margin:.35em 0;font-size:clamp(1rem,1.4vw,1.125rem);line-height:1.6;color:rgba(251,250,247,.75); }
.shr-s-masthead .shr-e-lede :is(strong,b){ color:var(--shr-ivory);font-weight:500; }
.shr-s-masthead .shr-e-lede a:not(.shr-pill):not(.shr-e-btn-outline){ color:var(--shr-ivory);text-decoration:none;border-bottom:1px solid rgba(251,250,247,.35); }
.shr-s-masthead .shr-e-lede a:not(.shr-pill):not(.shr-e-btn-outline):hover{ color:var(--shr-blue-lift);border-bottom-color:currentColor; }
.shr-s-masthead .shr-e-lede :is(.shr-pill,.shr-e-btn-outline){ margin-top:12px; }

.shr-c-media{ display:grid;gap:24px; }
.shr-c-photo{ margin:0; }
.shr-c-photo img{ display:block;width:100%;height:auto;max-width:min(100%,var(--shr-max,100%)) !important; }
.shr-e-section .shr-c-photo img[data-shr-natural]{ margin-left:0;margin-right:0; }
.shr-c-photo figcaption{ margin-top:12px; }
@media (min-width:1024px){
  .shr-c-grid--media .shr-c-details{ position:static;grid-column:1;grid-row:1; }
  .shr-c-grid--media .shr-c-sheetwrap{ grid-column:2;grid-row:1 / span 2; }
  .shr-c-grid--media .shr-c-media{ grid-column:1;grid-row:2; }
}

/* 1.46.3: the site's recognition, where a page carried a year-stamped award
   badge. The four marquee wins, two to a row whatever column holds them. */
.shr-s-recog{ margin:48px 0; }
.shr-s-recog:first-child{ margin-top:0; }
.shr-s-recog:last-child{ margin-bottom:0; }
.shr-s-recog .shr-e-eyebrow{ margin:0;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;font-size:.75rem;line-height:1.5;color:var(--shr-blue); }
.shr-s-recog .shr-l-marquee__grid{ margin-top:20px;gap:32px; }
@media (min-width:640px){ .shr-s-recog .shr-l-marquee__grid{ grid-template-columns:repeat(2,minmax(0,1fr));column-gap:48px; } }
.shr-s-recog .shr-l-marquee__year{ margin:0;font-family:var(--shr-font-mono);font-size:.75rem;line-height:1.5;letter-spacing:.14em;color:var(--shr-blue); }
.shr-s-recog .shr-l-marquee__item h3{ margin:12px 0 0;font-family:var(--shr-font-display);font-weight:400;font-size:clamp(1.25rem,1.8vw,1.5rem);line-height:1.3;color:var(--shr-harbour); }
.shr-s-recog .shr-l-marquee__body{ margin:12px 0 0;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;font-size:.75rem;line-height:1.6;color:var(--shr-slate); }
.shr-s-recog__more{ margin:36px 0 0; }
.shr-s-recog .shr-pill{ border-bottom-color:var(--shr-blue); }
.shr-bg-harbour .shr-s-recog :is(.shr-l-marquee__year,.shr-e-eyebrow){ color:var(--shr-blue-lift); }
.shr-bg-harbour .shr-s-recog .shr-l-marquee__item h3{ color:var(--shr-ivory); }
.shr-bg-harbour .shr-s-recog .shr-l-marquee__body{ color:rgba(251,250,247,.7); }

/* 1.46.4, from 17D. The recognition beneath a text and photo pair, at the
   section's full width: four across on a wide screen. */
.shr-s-recog-row{ margin-top:64px; }
.shr-s-recog-row .shr-s-recog{ margin:0; }
@media (min-width:1200px){ .shr-s-recog-row .shr-l-marquee__grid{ grid-template-columns:repeat(4,minmax(0,1fr)); } }
/* A landscape photograph beside long copy travels with it instead of ending
   above an empty column. Portrait frames are left alone: taller than the
   screen, they would be cut off while held. */
/* 1.74.4, from REPORT 37D. THE VOID.

   The rule above was written and never worked, because align-items:start on
   .shr-e-split shrank the media column to the height of the photograph. A
   sticky box cannot travel inside a box that is only as tall as itself, so
   the photograph simply stopped. On /services/retaining-wall-systems/ the
   section "The terrain doesn't forgive shortcuts" drew a 346px column of type
   1,799px tall beside a photograph that ended after 364px: roughly 1,435px of
   empty page down the right side, about three scrolls of nothing, on the
   first thing a buyer reads. "Built for the North Shore" left 641px. It was
   on every split row on the site.

   The COLUMN stretches, and the FIGURE travels inside it. Portrait frames
   stay put: taller than the screen, they would be held with their top cut
   off. */
@media (min-width:1024px){
  .shr-e-split{ align-items:stretch; }
  .shr-e-split__media > .shr-e-figure:is(.shr-e-3x2, .shr-e-4x3, .shr-e-16x9, .shr-e-natural){ position:sticky;top:126px; }
}
@media (min-width:1024px) and (min-height:820px){
  .shr-e-split__media > .shr-e-figure.shr-e-1x1{ position:sticky;top:126px; }
}
/* Articles: the recognition in the reading column. */
.shr-j-body .shr-s-recog{ margin:2.4em 0; }
.shr-j-body .shr-s-recog a.shr-pill{ text-decoration:none; }

/* ==========================================================================
   1.47.0, from Quentin's review during 18A
   ========================================================================== */

/* A. LOGOS IN THEIR OWN COLOURS. "Im seeing some logos on the site not with
   their color (theyre coming out grey)." Every mark, credential and award
   logo shows its own colours at rest. On a dark surface it sits on an ivory
   plate rather than being turned white, so its colours still read. */
img[data-shr-mark],
img[data-shr-mark]:hover,
.shr-s-mark__img,
.shr-e-cred__mark img,
.shr-e-cred--colour .shr-e-cred__mark img,
.shr-l-award__mark img{ filter:none !important;opacity:1 !important; }
.shr-bg-harbour .shr-s-mark__img,
.shr-bg-harbour .shr-e-cred__mark img{
  background:var(--shr-ivory);padding:12px 16px;box-sizing:content-box;
}

/* B. SELECTED WORK ON THE HOME PAGE: six projects, three to a row, and the
   words at a size a reader over fifty does not have to lean in for. */
@media (min-width:1280px){ .shr-work__grid{ grid-template-columns:repeat(3,minmax(0,1fr)); } }
.shr-card__desc{ font-size:16px;line-height:1.65;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden; }
.shr-card__name a{ color:inherit;text-decoration:none; }
.shr-card__name a:hover{ color:var(--shr-blue); }
.shr-card__link{ margin-top:14px;padding:6px 0; }

/* C. THE PHOTOGRAPHS OF A PROJECT, ORGANISED. */
.shr-p-photos__head{ display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:8px 32px; }
.shr-p-photos__head .shr-s-head{ margin-bottom:0; }
.shr-p-photos__count{
  margin:0 0 6px;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;color:var(--shr-slate);
}
.shr-p-hl{ display:grid;gap:12px;margin-top:40px;grid-template-columns:repeat(2,minmax(0,1fr)); }
@media (min-width:768px){ .shr-p-hl{ margin-top:56px; } }
.shr-p-hl__tile{
  position:relative;display:block;overflow:hidden;aspect-ratio:3/2;
  background:var(--shr-fill);outline-offset:4px;
}
.shr-p-hl__tile:first-child{ grid-column:1 / -1;aspect-ratio:4/3; }
.shr-p-hl__tile img{
  position:absolute;inset:0;display:block;width:100% !important;height:100% !important;max-width:none !important;
  object-fit:cover;transition:transform .9s cubic-bezier(.22,1,.36,1);
}
.shr-p-hl__tile:hover img,
.shr-p-hl__tile:focus-visible img{ transform:scale(1.035); }
.shr-p-hl__tag{
  position:absolute;left:16px;bottom:16px;padding:8px 12px;background:rgba(8,36,58,.82);color:var(--shr-ivory);
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;font-size:.75rem;
}
@media (max-width:899px){ .shr-p-hl__tile:nth-child(6){ display:none; } }
@media (min-width:900px){
  .shr-p-hl{ grid-template-columns:repeat(12,minmax(0,1fr));gap:16px; }
  .shr-p-hl__tile{ grid-column:span 4;aspect-ratio:3/2; }
  .shr-p-hl__tile:first-child{ grid-column:1 / span 8;grid-row:1 / span 2;aspect-ratio:auto; }
  .shr-p-hl__tile:nth-child(2),
  .shr-p-hl__tile:nth-child(3){ grid-column:9 / span 4; }
}
/* Small photographs: every tile the same modest size, none enlarged. */
.shr-p-hl--even .shr-p-hl__tile:first-child{ grid-column:auto;aspect-ratio:3/2; }
@media (max-width:899px){ .shr-p-hl--even .shr-p-hl__tile:nth-child(6){ display:block; } }
@media (min-width:900px){
  .shr-p-hl--even{ grid-template-columns:repeat(3,minmax(0,1fr)); }
  .shr-p-hl--even .shr-p-hl__tile,
  .shr-p-hl--even .shr-p-hl__tile:first-child,
  .shr-p-hl--even .shr-p-hl__tile:nth-child(2),
  .shr-p-hl--even .shr-p-hl__tile:nth-child(3){ grid-column:auto;grid-row:auto;aspect-ratio:3/2; }
}

.shr-p-rooms{ margin-top:56px; }
.shr-p-rooms__list{ display:grid;gap:16px;margin-top:20px;grid-template-columns:repeat(2,minmax(0,1fr)); }
@media (min-width:768px){ .shr-p-rooms__list{ grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px; } }
.shr-p-room{ display:block;text-decoration:none;color:var(--shr-harbour); }
.shr-p-room__frame{ position:relative;display:block;overflow:hidden;aspect-ratio:3/2;background:var(--shr-fill); }
.shr-p-room__frame img{ position:absolute;inset:0;width:100% !important;height:100% !important;max-width:none !important;object-fit:cover;transition:transform .9s cubic-bezier(.22,1,.36,1); }
.shr-p-room:hover .shr-p-room__frame img,
.shr-p-room:focus-visible .shr-p-room__frame img{ transform:scale(1.04); }
.shr-p-room__name{ display:block;margin-top:14px;font-family:var(--shr-font-display);font-size:1.3rem;line-height:1.2; }
.shr-p-room__count{ display:block;margin-top:6px;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;font-size:.75rem;color:var(--shr-slate); }
.shr-p-room:hover .shr-p-room__name{ color:var(--shr-blue); }

.shr-p-photos__all{ margin:48px 0 0; }
.shr-p-photos__all .shr-pill{ padding:18px 30px;font-size:.8125rem; }
.shr-p-all{ margin-top:48px; }
.shr-p-all > summary{ display:inline-flex;cursor:pointer;list-style:none; }
.shr-p-all > summary::-webkit-details-marker{ display:none; }
.shr-p-all__grid{ display:grid;gap:10px;margin-top:24px;grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); }
.shr-p-all__item{ display:block;aspect-ratio:3/2;overflow:hidden;background:var(--shr-fill); }
.shr-p-all__item img{ display:block;width:100%;height:100%;object-fit:cover; }
.shr-p-photos.is-viewer .shr-p-all{ display:none; }

/* D. THE VIEWER. Large, labelled controls; nothing moves on its own. */
html.shr-viewer-open{ overflow:hidden; }
.shr-viewer{
  position:fixed;inset:0;width:100%;height:100%;max-width:none;max-height:none;margin:0;padding:0;border:0;
  background:var(--shr-harbour);color:var(--shr-ivory);
}
.shr-viewer[open]{ display:grid;grid-template-rows:auto minmax(0,1fr) auto;grid-template-columns:minmax(0,1fr);overflow:hidden; }
.shr-viewer__bar,.shr-viewer__stage,.shr-viewer__foot,.shr-viewer__chapters,.shr-viewer__thumbs{ min-width:0; }
.shr-viewer::backdrop{ background:rgba(8,36,58,.96); }
.shr-viewer__bar{
  display:flex;flex-wrap:wrap;align-items:center;gap:12px 20px;padding:14px 16px;
  border-bottom:1px solid rgba(251,250,247,.14);
}
@media (min-width:768px){ .shr-viewer__bar{ padding:16px 28px; } }
.shr-viewer__title{ flex:1 1 auto;margin:0;font-family:var(--shr-font-display);font-size:1.25rem;line-height:1.2;color:var(--shr-ivory); }
.shr-viewer__chapters{ order:3;flex:1 1 100%;display:flex;flex-wrap:wrap;gap:8px; }
@media (min-width:1100px){ .shr-viewer__chapters{ order:0;flex:0 1 auto; } }
.shr-viewer__chip,
.shr-viewer__close,
.shr-viewer__nav{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:48px;padding:12px 18px;
  border:1px solid rgba(251,250,247,.4);border-radius:0;background:rgba(8,36,58,.72);color:var(--shr-ivory);cursor:pointer;
  font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.12em;font-size:.8125rem;line-height:1;white-space:nowrap;
  transition:background-color .25s ease,color .25s ease,border-color .25s ease;
}
@media (max-width:767px){ .shr-viewer__chip{ min-height:44px;padding:10px 12px;font-size:.75rem; } }
.shr-viewer__chip[aria-pressed="true"]{ background:var(--shr-ivory);color:var(--shr-harbour);border-color:var(--shr-ivory); }
.shr-viewer__chip:hover,
.shr-viewer__close:hover,
.shr-viewer__nav:hover{ background:var(--shr-ivory);color:var(--shr-harbour);border-color:var(--shr-ivory); }
.shr-viewer :focus-visible{ outline:2px solid var(--shr-blue-lift);outline-offset:3px; }
.shr-viewer__stage{ position:relative;margin:0;min-height:0;display:flex;align-items:center;justify-content:center;padding:16px; }
@media (min-width:768px){ .shr-viewer__stage{ padding:24px 136px; } }
.shr-viewer__img{
  display:block;width:auto;height:auto;max-width:min(100%, var(--w, 100%));max-height:100%;object-fit:contain;
  transition:opacity .35s ease;
}
.shr-viewer__img.is-loading{ opacity:.25; }
.shr-viewer__nav{ position:absolute;top:50%;transform:translateY(-50%);min-height:56px;padding:14px 20px; }
.shr-viewer__nav--prev{ left:16px; }
.shr-viewer__nav--next{ right:16px; }
.shr-viewer__nav[hidden]{ display:none; }
@media (max-width:767px){
  .shr-viewer__stage{ padding:12px 12px 84px; }
  .shr-viewer__nav{ top:auto;bottom:12px;transform:none;width:calc(50% - 18px); }
  .shr-viewer__nav--prev{ left:12px; }
  .shr-viewer__nav--next{ right:12px; }
}
.shr-viewer__foot{ padding:10px 16px 18px;display:grid;gap:12px;border-top:1px solid rgba(251,250,247,.14); }
@media (min-width:768px){ .shr-viewer__foot{ padding:12px 28px 22px; } }
.shr-viewer__count{
  margin:0;text-align:center;font-family:var(--shr-font-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:.8125rem;color:rgba(251,250,247,.86);
}
.shr-viewer__thumbs{ display:flex;gap:8px;overflow-x:auto;padding:2px 2px 6px;scrollbar-width:thin; }
.shr-viewer__thumb{
  flex:0 0 auto;width:84px;height:60px;padding:0;border:2px solid transparent;background:rgba(251,250,247,.08);
  opacity:.55;cursor:pointer;transition:opacity .2s ease,border-color .2s ease;
}
.shr-viewer__thumb:hover{ opacity:.9; }
.shr-viewer__thumb[aria-current="true"]{ opacity:1;border-color:var(--shr-ivory); }
.shr-viewer__thumb img{ display:block;width:100%;height:100%;object-fit:cover; }
@media (max-width:767px){ .shr-viewer__thumbs{ display:none; } }
@media (prefers-reduced-motion:reduce){
  .shr-p-hl__tile img,.shr-p-room__frame img,.shr-viewer__img{ transition:none; }
  .shr-p-hl__tile:hover img,.shr-p-room:hover .shr-p-room__frame img{ transform:none; }
}

/* ==========================================================================
   1.47.1, from 18A: whole photographs on phones
   ========================================================================== */

/* A. The opening photograph on a phone. As a cover behind the title in a
   band 450 to 830px tall, it showed 26 to 62 percent of its width. On a
   phone it now sits above the title at its own shape, whole, below the
   header, and the title follows on the dark band. */
@media (max-width:767px){
  .shr-s-masthead--image{ padding-top:88px; }
  .shr-s-masthead--image .shr-s-masthead__bg{
    position:relative;inset:auto;margin:0 -20px 36px;overflow:hidden;transform:none !important;will-change:auto;
  }
  .shr-s-masthead--image .shr-s-masthead__bg img{ width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;object-position:50% 38%; }
  .shr-s-masthead--image::after{ content:none; }
  .shr-s-hero-strip img{ aspect-ratio:4/3;height:auto;object-fit:cover;object-position:50% 38%; }
}

/* B. Section photographs on a phone are shown whole: the frame shapes that
   keep a desktop page in rhythm cropped a wide photograph to 65 to 73 percent
   in a single phone column. */
@media (max-width:767px){
  /* 1.69.1: .shr-e-3x4 is out of this list. It is the portrait frame, and
     squeezing a portrait into 4:3 is the crop this rule exists to prevent. */
  .shr-e-figure:is(.shr-e-4x3,.shr-e-3x2,.shr-e-16x9,.shr-e-1x1) img{ aspect-ratio:4/3;height:auto;object-fit:cover;object-position:50% 40%; }
}

/* B2. A portrait photograph keeps its own shape on a phone. 1.69.1.
   Quentin, 23 September, with a screenshot: Mark Cooper's headshot was cropped
   on the phone. The rule above forced every section photograph into 4:3, which
   is right for a wide photograph in a single column and wrong for a face. The
   shape of the file decides here, not the frame class, so this holds for any
   portrait in editorial content and touches no landscape photograph at all. */
@media (max-width:767px){
  .shr-e-figure img[data-shr-portrait],
  .shr-e-section img[data-shr-portrait],
  .shr-s-section img[data-shr-portrait]{
    aspect-ratio:var(--shr-ar, 3/4) !important;
    height:auto !important;
    object-fit:contain !important;
    object-position:50% 50% !important;
  }
}

/* C. Journal cards on a phone: a 3:2 frame, so a 16:9 photograph shows 84
   percent of its width, not 74.9. */
@media (max-width:767px){ .shr-j-card__figure img{ aspect-ratio:3/2; } }

/* =============================================================================
   1.48.0. KATHLEEN'S REVIEW, 22 SEPTEMBER 2026.

   Her list, in her order, with the rule each one answers. Nothing here changes
   an address, and nothing here invents content: every removal takes something
   off the screen and every addition dresses something the site already has.
   ========================================================================== */

/* 3. The wordmark, larger. She asked for about 4 by 1.5 inches. The mark is
   1813 by 364, so 68px of height draws it about 339px wide on a wide screen. */
.shr-brand__logo{ height:44px; }
@media (min-width:1024px){ .shr-brand__logo{ height:60px; } }
@media (min-width:1440px){ .shr-brand__logo{ height:68px; } }

/* 4. Nothing dotted on anything a visitor is meant to press. The motif is out
   of the markup; this is the guard for any that is cached or inherited. */
.shr-pill .shr-dots,
.shr-brand .shr-dots,
.shr-footer__mark .shr-dots,
.shr-mobile__cta .shr-dots{ display:none; }

/* 6. The phone number is out of the top banner. */
.shr-header__phone{ display:none; }

/* 8. The opening: Mark's words beside a photograph, the four pillars beneath.
   One band, so the quote and the four words read as one idea. */
.shr-opening{ text-align:left; padding:64px 20px 0; }
@media (min-width:768px){ .shr-opening{ padding:120px 40px 0; } }
.shr-opening__inner{
  max-width:1400px;margin:0 auto;display:grid;gap:40px;align-items:center;
}
@media (min-width:900px){
  .shr-opening__inner{ grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:80px; }
}
.shr-opening__media{ margin:0;line-height:0; }
.shr-opening__img{
  /* 1.69.2. The frame takes its shape from the file, which front-page.php
     passes in as --shr-ar. Mark's portrait is 1200 by 1600 and is shown whole.
     The phone rule below used to force 4:3 for a calmer column and took the
     top of his head with it, which is the one thing a headshot cannot lose. */
  width:100%;height:auto;display:block;
  aspect-ratio:var(--shr-ar, 3/4);
  object-fit:cover;
}
@media (max-width:899px){ .shr-opening__img{ aspect-ratio:var(--shr-ar, 3/4);object-position:50% 50%; } }
.shr-opening__quote{ margin-left:0;margin-right:0;text-wrap:balance; }
.shr-opening__rule{ margin-left:0; }
.shr-opening__sig{ text-align:left; }

/* The pillars, now four and inside the opening band. */
.shr-pillars{ padding:56px 20px 64px; }
@media (min-width:768px){ .shr-pillars{ padding:96px 40px 140px; } }
@media (min-width:768px){
  .shr-pillars__grid{ grid-template-columns:repeat(2,1fr);gap:48px 40px; }
}
@media (min-width:1024px){
  .shr-pillars__grid{ grid-template-columns:repeat(4,1fr);gap:40px; }
}
.shr-pillar{ text-align:left; }
.shr-pillar__hair{ margin-bottom:24px; }
.shr-pillar h3{ margin-top:0; }
@media (min-width:768px){ .shr-pillar h3{ margin-top:0;font-size:32px; } }

/* 10. "Why Shakespeare Homes" reads as a heading, in ivory, and the note sits
   beside the words so the band is not mostly empty navy. */
.shr-manifesto{ padding:64px 20px; }
@media (min-width:768px){ .shr-manifesto{ padding:112px 40px; } }
.shr-manifesto__inner{ display:grid;gap:48px;align-items:center; }
@media (min-width:1024px){
  .shr-manifesto__inner{ grid-template-columns:minmax(0,7fr) minmax(0,4fr);gap:80px; }
}
.shr-manifesto__title{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(2rem,4.4vw,3.4rem);line-height:1.1;color:var(--shr-ivory);
  max-width:22ch;text-wrap:balance;
}
.shr-manifesto__cols{ margin-top:32px; }
@media (min-width:768px){ .shr-manifesto__cols{ margin-top:40px;gap:48px; } }
@media (min-width:1024px){ .shr-manifesto__cols{ grid-template-columns:repeat(2,1fr);gap:48px; } }
.shr-manifesto__cols p{ font-size:18px;color:rgba(251,250,247,.92); }
.shr-manifesto__memowrap{ margin-top:0;justify-content:center; }
.shr-manifesto__shapes span{ opacity:.5 !important; }

/* 11. The project cards carry a name and a link, nothing else. */
.shr-card__name{ margin-top:20px; }
.shr-card__link{ margin-top:12px; }

/* 12. Recognition, rebuilt. The count leads, the four wins sit as cards, and
   the awarding bodies appear in their own colours (rule 16). */
.shr-recognition__head{ display:grid;gap:32px;align-items:center; }
@media (min-width:900px){
  .shr-recognition__head{ grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:64px; }
}
.shr-recognition__figure{
  border-top:1px solid rgba(251,250,247,.28);padding-top:20px;
}
.shr-recognition__count{
  display:block;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(4.5rem,13vw,9rem);line-height:.9;color:var(--shr-ivory);
  font-variant-numeric:tabular-nums;
}
.shr-recognition__figure p{ margin:12px 0 0;color:rgba(251,250,247,.72);font-size:12px; }
.shr-recognition__intro h2{ margin-top:0; }
@media (min-width:768px){
  .shr-recognition__intro h2{ margin-top:0;font-size:clamp(1.9rem,3.6vw,3rem); }
}
.shr-recognition__all{
  display:inline-block;margin-top:24px;color:var(--shr-ivory);text-decoration:none;
  border-bottom:1px solid rgba(251,250,247,.4);padding-bottom:4px;
}
.shr-recognition__all:hover{ border-bottom-color:var(--shr-ivory); }
.shr-recognition__awards{ margin-top:48px; }
@media (min-width:768px){ .shr-recognition__awards{ margin-top:72px; } }
.shr-award__body{ margin:12px 0 0;color:rgba(251,250,247,.66); }
.shr-recognition__bodies{
  margin-top:48px;padding-top:40px;border-top:1px solid rgba(251,250,247,.18);
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:20px;
}
@media (min-width:768px){ .shr-recognition__bodies{ margin-top:64px;gap:32px; } }
@media (min-width:768px){ .shr-recognition{ padding-top:112px;padding-bottom:112px; } }

/* The ivory plate. Rule 16: a logo keeps its own colours, so a dark mark gets
   a light ground to sit on rather than being knocked out to white. */
.shr-plate{
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--shr-ivory);border-radius:2px;padding:14px 16px;
  min-height:64px;max-width:100%;min-width:0;box-sizing:border-box;
}
.shr-plate__mark{
  display:block;width:auto;height:auto;max-height:36px;max-width:100%;
  filter:none !important;mix-blend-mode:normal;
}
.shr-plate--lg{ padding:16px;min-height:88px; }
.shr-plate--lg .shr-plate__mark{ max-height:52px;max-width:100%; }
@media (min-width:768px){ .shr-plate{ padding:14px 20px; } .shr-plate--lg{ padding:18px 24px;min-height:96px; } }
.shr-plate--word{
  color:var(--shr-harbour);letter-spacing:.14em;text-transform:uppercase;
}

/* 13. The certification banner, larger, with the real marks. */
.shr-certs{ padding:56px 20px; }
@media (min-width:768px){ .shr-certs{ padding:88px 40px; } }
.shr-certs__inner{ max-width:1400px;margin:0 auto;text-align:center; }
.shr-certs__head{ margin:0 0 32px;color:var(--shr-slate); }
@media (min-width:768px){ .shr-certs__head{ margin-bottom:44px; } }
.shr-certs__grid{
  align-items:stretch;justify-items:center;
  grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;
}
@media (min-width:481px){ .shr-certs__grid{ grid-template-columns:repeat(2,minmax(0,1fr));gap:24px; } }
@media (min-width:768px){ .shr-certs__grid{ grid-template-columns:repeat(4,minmax(0,1fr));gap:28px; } }
@media (min-width:1200px){ .shr-certs__grid{ grid-template-columns:repeat(7,minmax(0,1fr));gap:20px; } }
.shr-cert{
  width:100%;min-width:0;justify-content:center;
  min-height:88px;background:#fff;border:1px solid rgba(90,107,120,.16);
  padding:14px 12px;box-sizing:border-box;
}
@media (min-width:768px){ .shr-cert{ min-height:96px; } }
.shr-cert--mark{ padding:0;border:0;background:transparent; }
.shr-cert--mark .shr-plate{
  width:100%;height:100%;background:#fff;border:1px solid rgba(90,107,120,.16);
}
.shr-certs .shr-cert__icon{ height:26px;width:26px; }
.shr-certs .shr-cert p{ margin-top:10px; }

/* 15, 21, 34, 38. One closing band, shorter: a heading, one line, one button
   and the phone number. */
.shr-s-cta-band{ padding-top:72px;padding-bottom:72px; }
@media (min-width:768px){ .shr-s-cta-band{ padding-top:96px;padding-bottom:96px; } }
.shr-s-cta-band .shr-e-rule{ display:none; }
.shr-s-cta-band :where(h2){ font-size:clamp(1.9rem,3.8vw,2.9rem);max-width:18ch; }
.shr-s-cta-band__lede{
  margin:22px 0 0;max-width:52ch;
  font-family:var(--shr-font-sans);font-size:17px;line-height:1.7;
  color:rgba(251,250,247,.78);
}
.shr-s-cta-band__lede :where(p){
  margin:0;font-family:inherit;font-size:inherit;line-height:inherit;color:inherit;
}
.shr-s-cta-band__lede :where(p) + :where(p){ margin-top:14px; }
@media (min-width:1024px){
  .shr-s-cta-band__grid{ grid-template-columns:minmax(0,7fr) minmax(0,5fr);align-items:center;column-gap:64px; }
}
.shr-s-cta-band__actions{ margin:0;justify-content:flex-start; }
@media (min-width:1024px){ .shr-s-cta-band__actions{ justify-content:flex-end; } }

/* 37. "More articles" carries a thumbnail where the article has one. */
.shr-j-list__thumb{
  flex:0 0 auto;width:96px;height:64px;overflow:hidden;background:rgba(90,107,120,.12);
}
.shr-j-list__thumb img{ width:100%;height:100%;object-fit:cover;display:block; }
.shr-j-list__thumb--none{ background:rgba(90,107,120,.08); }
.shr-j-list a{ display:flex;align-items:center;gap:20px; }
.shr-j-list__text{ display:flex;flex-direction:column;gap:6px;min-width:0; }
@media (max-width:520px){
  .shr-j-list__thumb{ width:72px;height:52px; }
  .shr-j-list a{ gap:14px; }
}

/* =============================================================================
   1.49.0. THE PREMIUM PASS.

   1.48.x answered Kathleen's list on the home page. This is the pass over
   every other page type, judged against the standard written in
   18A-2-premium-audit-draft.md: readable without leaning in, calm, one clear
   next step, photography that leads, and nothing that looks like 2019.

   The largest single finding is not a matter of taste. The accent blue reads
   at 2.63:1 against Deep Harbour, and 4.5:1 is the floor for body type. Every
   dark band on this site, which includes the first screen of almost every
   page, carried blue type. That is fixed here, sitewide, in one place.
   ========================================================================== */

/* ---- 1. Type on a dark ground ------------------------------------------- */

.shr-e-masthead .shr-e-eyebrow,
.shr-bg-harbour .shr-e-eyebrow,
.shr-bg-harbour .shr-eyebrow,
.shr-bg-harbour .shr-eyebrow--blue,
.shr-manifesto__inner .shr-eyebrow,
.shr-e-masthead .shr-e-eyebrow .elementor-heading-title,
.shr-bg-harbour .shr-e-eyebrow .elementor-heading-title{
  color:var(--shr-sky);
}
.shr-e-masthead .shr-e-rule,
.shr-bg-harbour .shr-e-rule{ background:var(--shr-sky); }
.shr-bg-harbour :where(a):hover{ color:var(--shr-sky); }
.shr-bg-harbour .shr-stat__num{ color:var(--shr-sky); }
.shr-award{ border-color:rgba(156,200,236,.38); }
.shr-award__year{ color:var(--shr-sky); }
.shr-e-crumbs,
.shr-e-crumbs a{ color:rgba(251,250,247,.68); }
.shr-recognition__lede{ font-size:17px;color:rgba(251,250,247,.82); }
@media (min-width:768px){ .shr-recognition__lede{ font-size:18px; } }

/* The focus ring has to be visible on both grounds or keyboard users lose
   their place on every dark band. */
.shr-bg-harbour :where(a,button,summary,input,select,textarea):focus-visible,
.shr-e-masthead :where(a,button,summary):focus-visible,
.shr-footer :where(a,button):focus-visible,
.shr-header :where(a,button):focus-visible{
  outline:2px solid var(--shr-sky);outline-offset:3px;
}

/* ---- 2. Reading size ----------------------------------------------------- */
/* 17px is the floor, not the target. On a wide screen the same paragraph gets
   18px and a little more leading, which is the difference between reading a
   service page and skimming it. The measure is unchanged, so the line length
   stays inside 70 characters. */

@media (min-width:1024px){
  .shr-e-prose p,.shr-e-article p,
  .shr-e-prose li,.shr-e-article li{ font-size:18px;line-height:1.75; }
  .shr-e-lede{ font-size:22px;line-height:1.6; }
  .shr-e-prose p + p,.shr-e-article p + p{ margin-top:26px; }
}
.shr-e-masthead .shr-e-lede{ max-width:40rem; }

/* ---- 3. Section openings ------------------------------------------------- */
/* A heading that arrives with air above it and a hairline below reads as a
   chapter. The numeral that used to do this job is gone (1.48.0). */

.shr-s-head{ position:relative;padding-top:4px; }
.shr-s-head .shr-e-rule{ width:56px;height:2px;margin:0 0 22px; }
.shr-s-head :where(h2){ text-wrap:balance; }
@media (min-width:1024px){
  .shr-s-head :where(h2){ font-size:clamp(2rem,3.4vw,2.9rem);line-height:1.12; }
}

/* ---- 4. Controls --------------------------------------------------------- */
/* Every control a visitor has to hit is at least 44px tall at every width.
   Mark's clients are mostly over fifty and many of them are on a phone. */

.shr-pill,
.elementor-button.shr-e-btn-outline,
.shr-e-btn-outline .elementor-button,
.shr-s-call,
.shr-stickybar a,
.shr-work__all,
.shr-card__link,
.shr-recognition__all{
  min-height:44px;display:inline-flex;align-items:center;
}
.shr-pill{ padding:15px 26px; }
.shr-rail a{ min-height:44px;min-width:44px; }
.shr-j-list a{ min-height:64px; }

/* ---- 5. The certification row, legible -----------------------------------
   K1-2 measured the marks at 52px tall, at which the small type inside the
   RenoMark, CHBA and 2-5-10 badges does not read. Four across instead of
   seven gives each mark a wider tile and 72px of height, and no mark is
   drawn larger than its file. */

/* Flex, not grid: seven marks in a four column grid leave an empty cell, and
   a half empty row is one of the things this pass is meant to remove. Wrapped
   and centred, the seven read as one block. */
.shr-certs__grid{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:stretch;gap:16px;
}
.shr-certs__grid > *{ flex:0 1 calc(50% - 8px); }
@media (min-width:768px){
  .shr-certs__grid{ gap:24px; }
  .shr-certs__grid > *{ flex:0 1 calc(25% - 18px); }
}
@media (min-width:1200px){
  .shr-certs__grid{ gap:28px; }
  .shr-certs__grid > *{ flex:0 1 calc(25% - 21px); }
}
.shr-cert{ min-height:104px; }
@media (min-width:768px){ .shr-cert{ min-height:120px; } }
.shr-plate--lg .shr-plate__mark{ max-height:64px; }
@media (min-width:768px){ .shr-plate--lg .shr-plate__mark{ max-height:72px; } }

/* ---- 6. The journal list ------------------------------------------------- */
/* An article with no picture now keeps its place in the row without drawing a
   grey block, which read as a broken image. */

.shr-j-list__thumb--none{ background:transparent; }

/* ---- 7. Photography that leads ------------------------------------------- */
/* The first photograph on an engine page is given the full width of the band
   rather than a column, so a service page opens the way a project page does.
   Everything after it keeps the existing rhythm. */

.shr-e-section .shr-e-figure img{ transition:transform .8s cubic-bezier(.2,.7,.2,1); }
/* WITHDRAWN at 1.83.13. This rule set every split photograph on the site to
   4:3 at desktop, whatever the file was and whatever frame class
   shr_sections_ratio() had chosen for it. It cancelled that function outright.
   See section 65.2. */
@media (prefers-reduced-motion:reduce){
  .shr-e-section .shr-e-figure img{ transition:none; }
}

/* ---- 8. Nothing crowded on a phone --------------------------------------- */
@media (max-width:767px){
  .shr-e-section{ padding:56px 20px; }
  .shr-e-section--tall{ padding:64px 20px; }
  .shr-s-head :where(h2){ font-size:clamp(1.6rem,7vw,2.1rem);line-height:1.15; }
  .shr-e-masthead{ padding:120px 20px 56px; }
}


/* =============================================================================
   1.49.1. FROM K2-B.

   The About page's principles went from eight to four (Kathleen's request), and
   four items in a three column grid leave one card alone on the second row.
   A half empty row is one of the things the premium pass exists to remove, so
   a numbered list that holds exactly four items becomes two by two.

   Written to match whichever way the block is marked up, and harmless if it
   matches neither: an unmatched :has() selector does nothing.
   ========================================================================== */

@media (min-width:768px){
  .shr-e-numbered--three:has(> .shr-e-step:nth-child(4)):not(:has(> .shr-e-step:nth-child(5))),
  .shr-e-numbered--three:has(> *:nth-child(4)):not(:has(> *:nth-child(5))),
  .shr-e-numbered:has(> .shr-e-step:nth-child(4)):not(:has(> .shr-e-step:nth-child(5))){
    grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:64px;
  }
}

/* The four read as paragraphs, not captions, so they want a reading measure
   rather than a narrow column. */
@media (min-width:768px){
  .shr-e-numbered--three:has(> *:nth-child(4)):not(:has(> *:nth-child(5))) .shr-e-step p{
    max-width:46ch;
  }
}

/* =============================================================================
   1.50.0. FROM 18A-2.

   The audit rated 41 of 72 sections Below standard and answered its last
   question, "would a fifty-five year old think this was built cheaply", with
   a yes and seven reasons. This is the pass that answers those reasons.

   The worst finding was mine. 1.47.1 set out to show section photographs
   whole on a phone by taking their aspect ratio away. WordPress 6.7 then
   started writing sizes="auto", and between the two, 19 photographs were
   drawn 350 by 1500, stretched out of shape, on the four service pages. Both
   halves are fixed above and in functions.php: on a phone a section
   photograph now sits in a generous 4:3 frame and is never distorted.
   ========================================================================== */

/* ---- 1. Type on a dark ground, the part 1.49.0 missed -------------------- */
/* The footer column headings were still the accent blue on Deep Harbour,
   which measures 2.63:1 at 11px. */

.shr-footer__colhead{ color:var(--shr-sky); }
.shr-footer a:hover{ color:var(--shr-sky); }

/* ---- 2. Reading size. 16px is the floor, everywhere in the main content -- */
/* 18A-2 found body copy at 15px on the home page, the journal and three
   service mastheads, and 14.6px on the contact page and in the closing band
   on a phone. None of it was a deliberate choice; they are all defaults that
   were never raised. */

.shr-build__copy p,
.shr-card__desc,
.shr-j-card__excerpt,
.shr-j-lead__excerpt,
.shr-quote__name,
.shr-recognition__lede,
.shr-s-cta-band__lede,
.shr-s-cta-band__lede p,
.shr-contact__lede,
.shr-contact__sheetlede,
.shr-contact__addr,
.shr-contact__addr p,
.shr-j-list__meta{ font-size:16px; }

/* 1.84.1: .shr-post__title WAS IN THE LIST ABOVE. This block exists to raise a
   16px floor under body copy. A journal card title is not body copy, and its
   own base rule at line 1348 sets it to 24px. Sitting in this list, later in
   the file, the floor was overriding the title and PUSHING IT DOWN to 16px,
   next to a 76px section heading.

   Kathleen, round 4: "From the Journal; The titles have gone back to being
   very small again... The previous iteration was lovely and had already
   addressed this note. Please revert it back to be larger headings."

   The previous iteration is the 24px base rule. Removing the title from this
   list restores it. Measured on the live page with the candidate applied:
   16px to 24px, two lines, 422px inside a 422px card, no overflow. */

@media (min-width:768px){
  .shr-build__copy p,
  .shr-card__desc,
  .shr-j-card__excerpt,
  .shr-j-lead__excerpt,
  .shr-contact__lede,
  .shr-contact__sheetlede{ font-size:17px; }
}

/* 16px is a floor, not a ceiling: the lede stays the lede. */
.shr-e-masthead .shr-e-lede,
.shr-e-masthead .shr-e-lede p{ font-size:19px; }
@media (min-width:1024px){
  .shr-e-masthead .shr-e-lede,
  .shr-e-masthead .shr-e-lede p{ font-size:22px;line-height:1.6; }
  .shr-s-cta-band__lede, .shr-s-cta-band__lede p{ font-size:18px; }
}

/* The mono labels are labels, not reading matter, but 10px is too small for
   anyone over fifty. 12px is the floor for those too. */
.shr-mono-sm,
.shr-eyebrow,
.shr-e-eyebrow,
.shr-e-crumbs,
.shr-e-crumbs a,
.shr-cert p,
.shr-stat p,
.shr-member__role,
.shr-e-person__role{ font-size:12px !important; letter-spacing:.12em; }
@media (min-width:768px){
  .shr-mono-sm, .shr-eyebrow, .shr-e-eyebrow{ font-size:12.5px !important; }
}

/* ---- 3. Tap targets. 44px, everywhere, at every width ------------------- */
/* The hero's frame buttons measured 68 by 3. Breadcrumb links measured 13
   tall. The footer's social icons were 20 by 29 with no words. */

.shr-segbar__seg{
  min-height:44px;display:flex;align-items:center;
  padding:0;background:none;border:0;cursor:pointer;
}
.shr-segbar__seg span{ display:block;width:100%; }

.shr-e-crumbs a,
.shr-card__link,
.shr-work__all,
.shr-j-list a,
.shr-post__tag,
.shr-footer__cols a,
.shr-footer__social a,
.shr-recognition__all,
.shr-build__link{
  display:inline-flex;align-items:center;min-height:44px;
}
.shr-footer__cols a{ display:inline-block;padding-block:11px;min-height:44px; }
.shr-footer__social a{ min-width:44px;justify-content:center; }
.shr-e-crumbs{ display:flex;flex-wrap:wrap;align-items:center;gap:0 6px; }

/* Anything the engine renders as an inline link inside prose keeps its place
   in the sentence but gains a comfortable hit area on a phone. */
@media (max-width:767px){
  .shr-e-prose a, .shr-e-article a{ padding:6px 0;display:inline-block; }
}

/* ---- 4. Line length ------------------------------------------------------ */
/* Five paragraphs on About ran 93 to 123 characters. */

.shr-e-section :where(.elementor-widget-text-editor, .elementor-widget-theme-post-content) p{
  max-width:68ch;
}

/* ---- 5. Balance. No half empty rows, no orphaned card ------------------- */
/* The Key Considerations lists hold seven items in a three column grid, which
   leaves one alone. Wrapped and centred, any count reads as one block. */

@media (min-width:768px){
  .shr-e-numbered--three:has(> *:nth-child(5)){
    display:flex;flex-wrap:wrap;justify-content:center;gap:48px 40px;
  }
  .shr-e-numbered--three:has(> *:nth-child(5)) > *{
    flex:0 1 calc(33.333% - 28px);min-width:0;
  }
}

/* ---- 6. The manifesto note, flat ---------------------------------------- */
.shr-manifesto__mark{
  margin:0;max-width:26rem;
  border-left:2px solid var(--shr-sky);padding:4px 0 4px 28px;
}
.shr-manifesto__mark blockquote{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.4rem,2.6vw,1.9rem);line-height:1.3;color:var(--shr-ivory);
}
.shr-manifesto__mark figcaption{ margin-top:16px;color:rgba(251,250,247,.7); }
.shr-manifesto__memowrap{ justify-content:flex-start; }

/* ---- 7. The portfolio grid, off the screen edge -------------------------- */
/* Project names sat against the edge of a phone with no margin. */

@media (max-width:767px){
  .shr-p-grid, .shr-p-cards, .shr-p-main .shr-e-inner{ padding-left:20px;padding-right:20px; }
  .shr-p-card__name, .shr-p-card__meta{ padding-left:0;padding-right:0; }
}

/* ---- 8. The contact sheet, flat ----------------------------------------- */
/* Graph paper and a drop shadow, with a 39px submit button. */

.shr-contact__sheet, .shr-c-form, .shr-memo__sheet{
  box-shadow:none !important;background-image:none !important;
}
.shr-contact__rules, .shr-memo__rules, .shr-memo__clip{ display:none !important; }
body .gform_wrapper.gravity-theme .gform_footer input[type=submit],
body .gform_wrapper.gravity-theme .gform_footer button{
  min-height:56px;padding:0 36px;font-size:13px;letter-spacing:.14em;
}
@media (max-width:767px){
  body .gform_wrapper.gravity-theme .gform_footer input[type=submit],
  body .gform_wrapper.gravity-theme .gform_footer button{ width:100%; }
}
body .gform_wrapper.gravity-theme .gchoice input[type=radio],
body .gform_wrapper.gravity-theme .gchoice input[type=checkbox]{
  width:24px;height:24px;
}
body .gform_wrapper.gravity-theme .gchoice{ min-height:44px;display:flex;align-items:center;gap:10px; }

/* ---- 9. A video on a page is a video, not a bare player ------------------ */
/* 18A-2 saw "0:00" and a black caption on Complex Site Development. */

.shr-e-section figure:has(> video){ margin:0; }
.shr-e-section video{
  display:block;width:100%;height:auto;background:var(--shr-harbour);
}
.shr-e-section figure:has(> video) figcaption{
  margin-top:14px;font-family:var(--shr-font-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:12px;color:var(--shr-slate);
}
.shr-bg-harbour .shr-e-section figure:has(> video) figcaption{ color:rgba(251,250,247,.7); }

/* ---- 10. Nothing moves on its own --------------------------------------- */
/* The JavaScript no longer starts either slideshow. This is the guard. */

.shr-hero__img{ transition:opacity .45s ease; }
.shr-quote{ transition:opacity .3s ease; }
@media (prefers-reduced-motion:reduce){
  .shr-hero__img, .shr-quote{ transition:none; }
}


/* =============================================================================
   1.50.1. FROM K3.

   The award list on About was crushing every title into a 110px column, and
   the cause was mine. The block was built as year | name | body, and 1.47.0
   removed the year paragraph without touching the grid, so the name inherited
   the year's column. It is not only About: every engine page that carries the
   recognition block had it.
   ========================================================================== */

@media (min-width:768px){
  .shr-e-win:not(:has(.shr-e-win__year)){
    grid-template-columns:minmax(0,1fr) auto;
    column-gap:40px;
  }
}
@media (max-width:767px){
  .shr-e-win__body{ white-space:normal; }
}

/* ---- The tiles that carry a name instead of a mark ---------------------- */
/* 18A-2 read "Ovation Awards" and "BC Energy Step Code" as placeholders,
   because a word sitting in a logo box looks like a logo that failed to load.
   Set as type, on the same plate, they read as a deliberate choice. Which
   they are: every Ovation file in this library is year stamped, and no Step
   Code mark exists anywhere. */

.shr-plate--word{
  font-family:var(--shr-font-display);font-weight:400;
  text-transform:none;letter-spacing:0;
  font-size:17px;line-height:1.25;text-align:center;
  color:var(--shr-harbour);padding:18px 22px;
}
@media (min-width:768px){ .shr-plate--word{ font-size:18px; } }
.shr-cert:not(.shr-cert--mark) p{
  font-family:var(--shr-font-display);font-weight:400;
  text-transform:none;letter-spacing:0;font-size:16px;line-height:1.3;
  color:var(--shr-harbour);margin-top:12px;
}
.shr-certs{ padding-bottom:40px; }
@media (min-width:768px){ .shr-certs{ padding-bottom:64px; } }

/* ---- The project masthead keeps the roof on the house ------------------- */
/* 18A-2 on Glencanyon: "the flagship dusk photo is buried under a navy scrim
   with the roof cut off". The crop showed too little of the top of the frame
   and the scrim was heavy enough to flatten what was left. */

.shr-s-masthead__bg img{ object-position:center 32%; }
.shr-s-masthead--image::after{
  background:
    linear-gradient(180deg, rgba(8,36,58,.80) 0%, rgba(8,36,58,.30) 40%, rgba(8,36,58,.78) 100%),
    linear-gradient(90deg, rgba(8,36,58,.62) 0%, rgba(8,36,58,.08) 62%);
}
@media (max-width:767px){
  .shr-s-masthead--image .shr-s-masthead__bg img{ object-position:50% 30%; }
}

/* ---- The portfolio's first screen --------------------------------------- */

.shr-p-more{ margin:48px 0 0;display:flex;justify-content:center; }
@media (min-width:768px){ .shr-p-more{ margin-top:64px; } }
.shr-p-more__btn{ cursor:pointer;font-family:var(--shr-font-mono); }
.shr-p-grid > [hidden]{ display:none !important; }


/* =============================================================================
   1.51.0. FROM 18A-3.

   The audit came back "No, not ready", and it was right. Three things were
   visibly broken, and all three were caused by a fix made somewhere else.
   That is the second night running, so each one is named here with its cause.
   ========================================================================== */

/* ---- 1. The hero headline ------------------------------------------------
   Withdrawn at 1.51.1. This block put all three lines in flow and showed them
   at load, to answer 18A-3's finding that the page had no h1. It answered the
   wrong half: it stacked the headline down the middle of the photograph and
   ran it up under the navigation, and the h1 was still only a frame of an
   animation. The h1 is a separate, permanent element in front-page.php now,
   and the lines are back on the scroll where they were designed to be. The
   printed-headline layout survives as the no-JavaScript and reduced-motion
   state, written into the base rules in section 9 rather than bolted on here.
   ------------------------------------------------------------------------- */

/* ---- 2. The segmented bars ----------------------------------------------
   1.50.0 gave the button a 44px hit area and the fill inherited it, so the
   active frame drew as a solid blue block and the rest vanished. The button
   stays 44px; the track goes back to being a track. */

.shr-segbar__seg{
  min-height:44px;display:flex;align-items:center;
  background:none !important;border:0;padding:0;cursor:pointer;
}
.shr-segbar__seg::before{
  content:"";display:block;width:100%;height:2px;
  background:rgba(251,250,247,.28);
}
.shr-segbar--dark .shr-segbar__seg::before{ background:rgba(8,36,58,.18); }
.shr-segbar__seg span{
  position:absolute;left:0;right:0;height:2px;
  background:var(--shr-ivory);transform:scaleX(0);transform-origin:left;
}
.shr-segbar--dark .shr-segbar__seg span{ background:var(--shr-harbour); }
.shr-segbar__seg{ position:relative; }
.shr-segbar__seg.is-active span{ transform:scaleX(1); }

/* ---- 3. The testimonial controls ----------------------------------------
   They grew to 44px and landed on top of the client's name. */

.shr-quotes__dots{
  display:flex;flex-wrap:wrap;justify-content:center;gap:4px;
  margin:40px 0 0;position:static;
}
.shr-dot{ min-width:32px;min-height:44px;display:flex;align-items:center;justify-content:center;background:none;border:0;cursor:pointer; }
.shr-dot span{ display:block;width:8px;height:8px;border-radius:50%;background:rgba(8,36,58,.25); }
.shr-dot.is-active span{ background:var(--shr-harbour); }
.shr-quotes__bar{ margin-top:20px; }
.shr-quotes__stage{ padding-bottom:8px; }

/* ---- 4. The contact form, flat. The 1.50.0 rule missed its class -------- */

.shr-c-media, .shr-c-form, .shr-c-sheet, .shr-contact__sheet,
[class*="shr-c-"][class*="sheet"], .shr-paper-grain{
  background-image:none !important;box-shadow:none !important;
  transform:none !important;border-radius:0 !important;
}
.shr-paper-grain::before, .shr-paper-grain::after{ content:none !important; }

/* ---- 5. Contrast, the last three places -------------------------------- */

.shr-footer__social a, .shr-footer__social svg{ color:var(--shr-sky); }
.shr-rail a, .shr-rail svg{ color:var(--shr-sky); }
/* A masthead lede over a photograph gets its own ground rather than hoping. */
.shr-s-masthead--image .shr-e-lede{
  background:rgba(8,36,58,.72);padding:18px 22px;border-radius:2px;
  backdrop-filter:blur(2px);
}
@media (max-width:767px){
  .shr-s-masthead--image .shr-e-lede{ background:none;padding:0;backdrop-filter:none; }
}

/* ---- 6. The rail stops sitting on the content --------------------------- */
/* At 1440 the fixed social rail covered the right 12px of every page. */

/* 1.52.0. 56px on the right only, from 1280 up, left the rail cutting across
   the award cards at 1440 by 12px and pulled every section 28px off centre.
   The gutter is reserved on both sides now, from the width the rail first
   appears, so the columns stay centred and nothing is underneath it. */
@media (min-width:768px){
  .shr-e-inner, .shr-e-narrow, .shr-e-prose,
  .shr-p-main .shr-e-inner, .shr-p-grid, .shr-e-masthead__inner{
    padding-inline:56px;
  }
}
@media (min-width:1024px){
  .shr-e-inner, .shr-e-narrow, .shr-e-prose,
  .shr-p-main .shr-e-inner, .shr-p-grid, .shr-e-masthead__inner{
    padding-inline:72px;
  }
}
.shr-totop, .shr-to-top, [class*="totop"], #ast-scroll-top{
  min-width:44px;min-height:44px;
}
/* 1.52.0. 18A-4 found it still overlapping the sticky Call bar by 15px at 390,
   because the control Astra prints is #ast-scroll-top and no selector here
   matched it. On a phone the sticky bar already holds the bottom of the
   screen, so there is nothing for a second control to do down there. */
@media (max-width:767px){
  .shr-totop, .shr-to-top, [class*="totop"], #ast-scroll-top{
    display:none !important;
  }
}

/* ---- 7. Tap targets, the ones 1.50.0 did not reach ---------------------- */

/* 1.52.0. THIS RULE BROKE THE PORTFOLIO. .shr-p-card is the whole card, a
   block link wrapping a 4:3 photograph and a name beneath it. display:
   inline-flex turned it into a row: the photograph shrank to whatever was
   left and the project name was squeezed into a 58px column beside it. It is
   the same mistake as .shr-e-win at 1.50.1, made by reaching for a display
   change to buy a tap target. A tap target is bought with padding.

   Nothing here changes an element's display any more. Cards are excluded
   entirely: their target is the whole card, which is already 300px tall. */
.shr-post__title a, .shr-card__name a, .shr-j-list__title,
.shr-e-person a, .shr-e-bio a,
.shr-contact__addr a, .shr-c-media a{
  padding-block:10px;
}
.shr-pill{ min-height:48px; }
@media (max-width:767px){
  .shr-footer__cols a{ min-height:44px; }
  .shr-j-list a{ min-height:72px; }
}
body .gform_wrapper.gravity-theme .gchoice{ min-height:48px; }
body .gform_wrapper.gravity-theme .gchoice label{ padding:10px 0;display:inline-block; }

/* ---- 8. The tiles that carry a name, sized like the marks beside them --- */

.shr-cert:not(.shr-cert--mark){ justify-content:center;text-align:center; }
.shr-cert:not(.shr-cert--mark) p{ font-size:17px;line-height:1.25;max-width:14ch; }
.shr-cert:not(.shr-cert--mark) .shr-cert__icon{ display:none; }
.shr-plate--word{ min-height:72px; }

/* ---- 9. One type system, including on the Elementor pages ---------------
   18A-3: /about-us/ and /about-us/team/ "switch headings to Montserrat". Two
   pages out of fifty using a different typeface is the clearest possible
   break of test 4e, and it happens because Elementor's own kit sets a family
   the child theme never overrode. */

.elementor-widget-heading .elementor-heading-title,
.elementor-widget-text-editor h1, .elementor-widget-text-editor h2,
.elementor-widget-text-editor h3, .elementor-widget-text-editor h4,
.elementor-widget-html h1, .elementor-widget-html h2,
.elementor-widget-html h3, .elementor-widget-html h4{
  font-family:var(--shr-font-display) !important;font-weight:400 !important;
}
.elementor-widget-text-editor, .elementor-widget-text-editor p,
.elementor-widget-html p, .elementor-widget-html li{
  font-family:var(--shr-font-sans) !important;
}
.elementor-widget-button .elementor-button,
.elementor-widget-heading .shr-e-eyebrow .elementor-heading-title{
  font-family:var(--shr-font-mono) !important;
}

/* The same reveal on every page needs the same starting state, or a section
   that JavaScript has not reached yet shows for a frame and then jumps. */
.js-motion .reveal-item{ will-change:transform,opacity; }
.js-motion .img-reveal{ will-change:transform; }


/* =============================================================================
   1.52.0. FROM 18A-4, AND THE FINISH PASS.

   The audit came back Premium 11 / Acceptable 7 / Below standard 7, "built
   cheaply: yes", and named the portfolio grid as the worst of it. That grid
   was broken by a rule written three releases earlier to buy a tap target,
   which is the third time in four nights that a blanket selector has broken a
   component it was never aimed at. Every fix below is scoped to the thing it
   is fixing.
   ========================================================================== */

/* ---- 1. The rem scale means what it says --------------------------------
   18A-4 1a found labels at 10.94px and 11.86px on a phone and nothing in this
   stylesheet asks for either. Astra's responsive typography shrinks the root
   to 14.58px below 768, so every .75rem label quietly became 10.94px. The
   scale here is written against a 16px root. */

@media (max-width:767px){
  html{ font-size:100%; }
}

/* ---- 2. The headline fits the phone -------------------------------------
   18A-4 Part 3: "We're Proven Here." broke as "We're Proven / Here." at 390,
   which leaves one word alone under a headline. */

.shr-hero__line{ text-wrap:balance; }
@media (max-width:767px){
  .shr-hero__line{ font-size:clamp(1.9rem,9.4vw,3.5rem); }
  .shr-hero__lines{ padding:0 16px; }
  .shr-js .shr-hero:not([data-still]) .shr-hero__line{ padding:0 16px; }
}

/* ---- 3. The award cards line up -----------------------------------------
   18A-4 Part 3: the Grand HAVAN title ran to three lines and the CHBA label
   broke with "· WINNER" alone on the second. Four cards in a row have to
   agree with each other whatever their titles do, so the label is pinned to
   the foot of the card and the phrase is balanced rather than broken. */

.shr-award{ display:flex;flex-direction:column;height:100%; }
.shr-award h3{ text-wrap:balance; }
.shr-award__body{ margin-top:auto;padding-top:18px;text-wrap:balance; }
@media (min-width:1024px){
  .shr-award__body{ letter-spacing:.10em; }
}

/* ---- 4. The footer columns ----------------------------------------------
   "Landscaping & Outdoor Living" wrapped at 1440 once the gutter was
   reserved for the rail. A service name reads as one thing, so it stays as
   one thing. */

.shr-footer__cols li{ font-size:16px;letter-spacing:.01em; }
.shr-footer__cols a{ text-wrap:balance; }
.shr-footer__legal{ text-wrap:balance; }
@media (max-width:767px){
  .shr-footer__legal{ font-size:12px;line-height:1.7; }
}

/* ---- 5. With JavaScript off ---------------------------------------------
   18A-4 2f. Nothing goes blank, which was the important part, but two things
   were unusable: the header stayed transparent all the way down the page, so
   the navigation sat white on cream at about 1.1:1, and seven of the eight
   testimonials could not be reached because the controls that reach them are
   script. Both are answered in CSS, which does not need script to work. */

html:not(.shr-js) .shr-header{
  background-color:var(--shr-chalk);
  border-bottom-color:var(--shr-blue);
}
html:not(.shr-js) .shr-nav a,
html:not(.shr-js) .shr-brand__name,
html:not(.shr-js) .shr-header__actions a{
  color:var(--shr-harbour);text-shadow:none;
}
html:not(.shr-js) .shr-quotes__stage{ min-height:0; }
html:not(.shr-js) .shr-quote{
  position:static;opacity:1;visibility:visible;
  padding-bottom:40px;
}
html:not(.shr-js) .shr-quote + .shr-quote{
  border-top:1px solid rgba(251,250,247,.18);padding-top:40px;
}
html:not(.shr-js) .shr-quotes__bar,
html:not(.shr-js) .shr-quotes__dots{ display:none; }

/* ---- 6. Motion parity, the last three places ----------------------------
   18A-4 2c named the About founder quote as the one section on any page that
   appears with no transition while its equivalent on the home page has one.
   The footer was the other. Both are tagged in main.js now; these are the
   styles that stop them flashing before the script reaches them. */

.shr-footer__cols > *, .shr-footer__brand{ will-change:opacity; }

/* ---- 7. The page is shorter ---------------------------------------------
   17,559px on a phone is twenty screens. The bands were built at desktop
   rhythm and carried it down unchanged. */

@media (max-width:767px){
  .shr-e-section{ padding-top:56px;padding-bottom:56px; }
  .shr-opening{ padding:52px 24px; }
  .shr-statement{ padding-top:64px;padding-bottom:64px; }
  .shr-recognition__awards{ margin-top:32px;gap:16px; }
  .shr-p-grid{ gap:28px; }
  .shr-quotes__stage{ margin-top:24px; }
}

/* ---- 8. Two last things 18A-4 caught -------------------------------------

   The admin bar below 782px is position:absolute, so it scrolls away, while
   the header was still holding a 46px offset for it. That offset is what put
   a strip of page above the header. Only anyone logged in ever saw it, which
   is the whole team and every test. */

@media screen and (max-width:782px){
  body.admin-bar .shr-header{ top:0; }
}

/* The enquiry form's radio and checkbox labels wrapped to two lines once the
   rem scale was corrected. They are choices, and a choice reads as one line. */

body .gform_wrapper.gravity-theme .gchoice label{
  font-size:16px;line-height:1.35;text-wrap:balance;
}
@media (min-width:768px){
  body .gform_wrapper.gravity-theme .gfield--type-radio .gfield_radio,
  body .gform_wrapper.gravity-theme .gfield--type-checkbox .gfield_checkbox{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px 32px;
  }
}


/* =============================================================================
   1.52.1. THE CREDENTIALS, AND WHY TWO OF THEM HAVE NO LOGO.

   18A-4 1j: Built Green and RenoMark render in black and white, and Ovation
   Awards and BC Energy Step Code are text tiles rather than marks.

   Checked at source tonight. The two colour files are real but member gated:
   RenoMark's are behind the CHBA member sign-in at chba.ca, and Built Green's
   are issued to member builders on request. Neither is public, and a mark
   lifted off somebody else's blog is both a licensing problem and exactly the
   cheapness this pass exists to remove.

   The other two have no current file to find. HAVAN's awards page calls the
   programme the HAVAN Awards for Housing Excellence, in its sixteenth year,
   and does not mention Ovation anywhere: Ovation is the retired GVHBA-era
   name. energystepcode.ca no longer resolves to a site at all, it redirects
   into the province's BC Codes pages under the 2024 code. Both brands are
   gone. There is nothing to fetch and there never will be.

   So the design stops depending on files that do not exist. A credential
   without a mark is set as type, deliberately, and never as a bordered box
   with nothing in it, which is what makes a visitor read it as broken. The
   marks that do exist keep their own colours, untouched. Rule 16 holds: it
   governs how a logo is shown, not whether every credential has to be one.
   ========================================================================== */

/* ---- The awarding bodies row, on harbour -------------------------------- */

.shr-recognition__bodies .shr-plate--word{
  background:none;border:0;border-radius:0;
  padding:0 10px;min-height:72px;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:23px;line-height:1.2;letter-spacing:.01em;
  color:var(--shr-ivory);
  position:relative;
  display:inline-flex;align-items:center;justify-content:center;
}
@media (min-width:768px){
  .shr-recognition__bodies .shr-plate--word{ font-size:27px;min-height:80px;padding:0 16px; }
}
/* A hairline in place of a ground, so it reads as one of the four and not as
   the one that failed to load. */
.shr-recognition__bodies .shr-plate--word::before{
  content:"";position:absolute;left:10px;right:10px;top:12px;height:1px;
  background:var(--shr-sky);opacity:.6;
}
@media (min-width:768px){
  .shr-recognition__bodies .shr-plate--word::before{ left:16px;right:16px;top:14px; }
}

/* Every mark in the row draws to the same optical height, so four different
   files read as one set. */
.shr-recognition__bodies .shr-plate{ min-height:72px; }
.shr-recognition__bodies .shr-plate__mark{ max-height:40px; }
@media (min-width:768px){
  .shr-recognition__bodies .shr-plate{ min-height:80px; }
  .shr-recognition__bodies .shr-plate__mark{ max-height:46px; }
}

/* ---- The certifications grid, on white ---------------------------------- */

.shr-certs .shr-cert:not(.shr-cert--mark){
  background:none;border:0;padding:0 8px;
  justify-content:center;
}
.shr-certs .shr-cert:not(.shr-cert--mark) p{
  position:relative;margin:0;padding-top:18px;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:19px;line-height:1.25;letter-spacing:.01em;
  max-width:15ch;color:var(--shr-harbour);
}
@media (min-width:768px){
  .shr-certs .shr-cert:not(.shr-cert--mark) p{ font-size:21px;max-width:16ch; }
}
.shr-certs .shr-cert:not(.shr-cert--mark) p::before{
  content:"";position:absolute;left:50%;transform:translateX(-50%);
  top:0;width:44px;height:1px;background:var(--shr-blue);opacity:.7;
}
.shr-plate--word{ min-height:0; }


/* =============================================================================
   1.53.0. ONE RHYTHM, LARGER MARKS, AND THE HERO PUT BACK.

   From 19A, measured on every page at 1440 and 390.

   The home page ran at five vertical rhythms at once (88, 112, 128, 144, 160)
   and the sharpest break was certs to quotes: 88/64 against 160/160. A page
   that breathes at five rates does not read as designed, it reads as sections
   pasted in from five places. One scale now, everywhere, on every page.
   ========================================================================== */

:root{
  --shr-band:64px;   /* phone   */
  --shr-band-lg:144px;  /* 1024 and up */
  --shr-band-md:104px;  /* 768 to 1023 */
  --shr-band-close:96px; /* the closing harbour band, deliberately tighter */
}

/* ---- 1. The scale -------------------------------------------------------- */

.shr-e-section, .shr-opening, .shr-build, .shr-manifesto, .shr-statement,
.shr-work, .shr-blueprint, .shr-recognition, .shr-certs, .shr-quotes,
.shr-journal, .shr-p-section{
  padding-top:var(--shr-band);
  padding-bottom:var(--shr-band);
}
@media (min-width:768px){
  .shr-e-section, .shr-opening, .shr-build, .shr-manifesto, .shr-statement,
  .shr-work, .shr-blueprint, .shr-recognition, .shr-certs, .shr-quotes,
  .shr-journal, .shr-p-section{
    padding-top:var(--shr-band-md);
    padding-bottom:var(--shr-band-md);
  }
}
@media (min-width:1024px){
  .shr-e-section, .shr-opening, .shr-build, .shr-manifesto, .shr-statement,
  .shr-work, .shr-blueprint, .shr-recognition, .shr-certs, .shr-quotes,
  .shr-journal, .shr-p-section{
    padding-top:var(--shr-band-lg);
    padding-bottom:var(--shr-band-lg);
  }
}
.shr-e-section.shr-bg-harbour:last-of-type,
.shr-closing{
  padding-top:var(--shr-band-close);
  padding-bottom:var(--shr-band-close);
}

/* The statement band carried 220px above its text and 220px below inside a
   720px section: over half of it was padding. Its inner is what was tall, so
   the inner is what comes down. */
.shr-statement__inner{ padding-block:0; }
.shr-statement{ min-height:0; }
@media (min-width:1024px){
  .shr-statement{ padding-top:128px;padding-bottom:128px; }
}

/* ---- 2. The mastheads ---------------------------------------------------
   Every page at 1440 left 668px of empty gutter to the right of its title,
   under a 240px top pad, identically on five pages. Repeated five times that
   is not restraint, it is one template stamp. The title takes the width it
   deserves, the top pad comes down to the header's own clearance plus one
   band, and the eyebrow and the rule carry the right hand side. */

.shr-e-masthead{ padding-top:calc(101px + var(--shr-band)); }
@media (min-width:1024px){
  .shr-e-masthead{ padding-top:calc(101px + 88px);padding-bottom:var(--shr-band-lg); }
  .shr-e-masthead__inner{ max-width:none; }
  .shr-e-masthead__inner > h1,
  .shr-e-masthead__inner > .shr-e-title{ max-width:20ch; }
  .shr-e-masthead .shr-e-lede{ max-width:52ch; }
}
/* A hairline the full width of the column, so the right hand side is holding
   something rather than sitting empty. */
@media (min-width:1024px){
  .shr-e-masthead__inner::after{
    content:"";display:block;margin-top:40px;height:1px;
    background:currentColor;opacity:.22;
  }
}

/* ---- 3. Headings sit with their own paragraph ---------------------------
   19A f: six headings on the home page sat closer to the paragraph above them
   than to their own paragraph below. A heading belongs to what follows it. */

.shr-manifesto h3, .shr-journal h3,
.shr-e-section h2, .shr-e-section h3,
.shr-p-story h3, .shr-s-section h3{
  margin-top:1.6em;margin-bottom:.45em;
}
.shr-manifesto h3:first-child, .shr-journal h3:first-child,
.shr-e-section h2:first-child, .shr-e-section h3:first-child{ margin-top:0; }

/* ---- 4. The marks, larger ------------------------------------------------
   Quentin: the logos need to be bigger and easier to see. They were drawn at
   72px in a 120px cell, which is a credential whispered. None is drawn larger
   than its own file, so nothing is upscaled. */

.shr-certs .shr-cert{ min-height:132px; }
@media (min-width:768px){ .shr-certs .shr-cert{ min-height:164px; } }
.shr-plate--lg{ padding:18px 20px; }
.shr-plate--lg .shr-plate__mark{ max-height:88px; }
@media (min-width:768px){
  .shr-plate--lg{ padding:22px 28px; }
  .shr-plate--lg .shr-plate__mark{ max-height:104px; }
}
.shr-recognition__bodies .shr-plate{ min-height:96px; }
.shr-recognition__bodies .shr-plate__mark{ max-height:56px; }
@media (min-width:768px){
  .shr-recognition__bodies .shr-plate{ min-height:112px;padding:16px 26px; }
  .shr-recognition__bodies .shr-plate__mark{ max-height:68px; }
  .shr-recognition__bodies .shr-plate--word{ min-height:112px;font-size:29px; }
}
.shr-certs__grid{ gap:20px; }
@media (min-width:768px){ .shr-certs__grid{ gap:24px; } }

/* Seven items wrapped 2+2+2+1 on a phone and left the last one alone. The
   credential that is set as type takes the full row instead, which is what it
   wants to be anyway, and the six marks pair off cleanly. */
@media (max-width:767px){
  .shr-certs .shr-cert:not(.shr-cert--mark){ flex:0 0 100%;min-height:0;padding:8px 0 0; }
  .shr-certs .shr-cert--mark{ flex:0 0 calc(50% - 10px); }
}

/* ---- 5. The testimonial dots stop overlapping ---------------------------
   19A h: 44px targets on a 32px pitch, so a thumb landing between two dots
   opened the wrong testimonial. A real bug, not a taste call. */

.shr-quotes__dots{ display:flex;justify-content:center;gap:8px; }
.shr-dot{ min-width:44px;flex:0 0 44px; }

/* ---- 6. The breadcrumb stops orphaning ---------------------------------- */

.shr-e-crumbs{ display:flex;flex-wrap:wrap;justify-content:center;gap:4px 10px; }
.shr-e-crumbs > *{ white-space:nowrap; }

/* ---- 7. Project highlights, equal height -------------------------------
   19A e: .shr-p-hl row one had a 535px item beside a 260px item. */

.shr-p-hl{ align-items:stretch; }
.shr-p-hl > *{ display:flex;flex-direction:column; }
.shr-p-hl figure, .shr-p-hl .shr-e-figure{ flex:1 1 auto;margin:0; }
.shr-p-hl img{ width:100%;height:100%;object-fit:cover; }

/* The two credentials that are set as type scale with the marks beside them,
   or they read as the small one in a row of large ones, which is the same
   failure in a different direction. */
.shr-certs .shr-cert:not(.shr-cert--mark) p{ font-size:23px; }
@media (min-width:768px){
  .shr-certs .shr-cert:not(.shr-cert--mark){ min-width:220px; }
  .shr-certs .shr-cert:not(.shr-cert--mark) p{ font-size:27px;max-width:13ch; }
  .shr-certs .shr-cert:not(.shr-cert--mark) p::before{ width:56px; }
}
@media (min-width:768px){
  .shr-recognition__bodies .shr-plate--word{ font-size:34px;padding:0 22px; }
  .shr-recognition__bodies .shr-plate--word::before{ left:22px;right:22px;top:22px; }
}


/* =============================================================================
   1.54.0. FROM THE 20A DESIGN REVIEW.

   Verdict was "no, I would not let this leave the studio", and the one thing
   stopping it was the home page hero: the headline under 4.5:1 on four of the
   five photographs and the navigation at 1.00:1 on the snow frame.

   Nothing goes over the photographs. Quentin has been clear twice and he is
   right. Each frame is instead cropped to put the words on the part of the
   picture that can carry them, and the one frame no crop can save changes the
   ink rather than the picture.
   ========================================================================== */

/* ---- 1. The hero frames --------------------------------------------------
   WITHDRAWN AT 1.59.0.

   This block cropped and zoomed four of the five photographs to push the
   headline onto darker pixels: object-position 50% 0% on frame 1, and
   transform:scale(1.25) and 1.5 anchored into a corner on frames 4 and 5.

   Two things were wrong with it. The headline is not on screen at load, so at
   the moment a visitor arrives the hero is nothing but the photograph, and
   all that cropping bought was rooflines cut off at the top of the frame and
   houses pushed out of their own composition. And scaling a photograph up by
   a quarter throws away a quarter of its resolution, on the one image on the
   site that has to look expensive.

   The frames go back to how they were composed: centred at desktop, with the
   deliberate mobile crops in section 4. Contrast for the headline is handled
   where the headline is, not by moving the house.
   ------------------------------------------------------------------------ */

/* ---- 2. The ink follows the picture -------------------------------------
   On the snow frame the headline and the navigation are Deep Harbour. Dark
   type on a white house under snow is a treatment a studio would choose, not
   a patch: 6.8:1 on the average backdrop and 13.3:1 on the brightest part. */

.shr-hero[data-ink="dark"] .shr-hero__line{
  color:var(--shr-harbour);
  text-shadow:0 1px 10px rgba(247,245,240,.75), 0 1px 2px rgba(247,245,240,.6);
}
html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-nav a,
html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-brand__name{
  color:var(--shr-harbour);
  text-shadow:0 1px 4px rgba(247,245,240,.8);
}

/* ---- 3. The navigation over a photograph --------------------------------
   20A: 13px ivory on a transparent header measured 1.00 to 2.67 on four of
   the five frames. This is a scrim on the HEADER, at the very top edge of the
   frame, which every masthead in this category has and which is not a band
   behind the headline. It is 96px tall and it is gone by the time the words
   arrive. */

.shr-header::before{
  content:"";position:absolute;inset-inline:0;top:0;height:120px;
  pointer-events:none;z-index:-1;
  background:linear-gradient(180deg, rgba(8,36,58,.72) 0%, rgba(8,36,58,.34) 52%, rgba(8,36,58,0) 100%);
  transition:opacity .4s ease;
}
.shr-header[data-solid="true"]::before{ opacity:0; }
.shr-nav a{ text-shadow:0 1px 4px rgba(8,36,58,.7); }
.shr-header[data-solid="true"] .shr-nav a{ text-shadow:none; }
/* On the snow frame the scrim would fight the picture, so it lifts and the
   navigation goes dark with the headline. */
html[data-hero-ink="dark"] .shr-header::before{ opacity:0; }

/* ---- 4. One type scale, not sixty-three ---------------------------------
   20A 2a counted 63 distinct size, weight, family and tracking combinations.
   A system is eight to twelve. Three groups were doing one job each. */

/* Every eyebrow is one eyebrow. Six versions existed, in three families. */
.shr-e-eyebrow, .shr-eyebrow,
.shr-mono-sm:not(.shr-plate--word):not(.shr-cert p),
.shr-certs__head,
.shr-p-card__meta, .shr-j-list__meta, .shr-award__body,
.shr-e-person__role, .shr-e-fact__label, .shr-e-crumbs{
  font-family:var(--shr-font-mono) !important;
  font-size:12px !important;
  font-weight:400 !important;
  letter-spacing:1.68px !important;
  text-transform:uppercase !important;
}

/* The two credentials that are set as type carry .shr-mono-sm in the markup
   and are not labels. They are restated after the rule above rather than
   excluded inside it, because :not() cannot reach a parent. */
.shr-certs .shr-cert:not(.shr-cert--mark) p.shr-mono-sm{
  font-family:var(--shr-font-display) !important;
  font-size:23px !important;font-weight:400 !important;
  letter-spacing:.01em !important;text-transform:none !important;
}
@media (min-width:768px){
  .shr-certs .shr-cert:not(.shr-cert--mark) p.shr-mono-sm{ font-size:27px !important; }
}
.shr-recognition__bodies .shr-plate--word.shr-mono-sm{
  font-family:var(--shr-font-display) !important;
  font-size:23px !important;font-weight:400 !important;
  letter-spacing:.01em !important;text-transform:none !important;
}
@media (min-width:768px){
  .shr-recognition__bodies .shr-plate--word.shr-mono-sm{ font-size:34px !important; }
}

/* Five section-title sizes on the home page alone: 93.6, 88, 79.2, 70.4 and
   54.4. One size. */
@media (min-width:1024px){
  .shr-opening h2, .shr-build h2, .shr-work h2, .shr-journal h2,
  .shr-recognition h2, .shr-quotes h2, .shr-manifesto__title,
  .shr-statement h2, .shr-blueprint h2{
    font-size:76px;line-height:1.06;letter-spacing:.01em;
  }
}

/* The interior pages spoke at 68 percent of the home page. They are the same
   site. */
@media (min-width:1024px){
  .shr-e-masthead h1, .shr-s-masthead h1{ font-size:96px; }
}
@media (min-width:768px) and (max-width:1023px){
  .shr-e-masthead h1, .shr-s-masthead h1{ font-size:64px; }
}

/* Body copy at 50+ does not sit under 1.6. */
.shr-e-prose p, .shr-p-story p, .shr-e-section p, .shr-s-section p{
  line-height:1.65;
}

/* ---- 5. The services masthead -------------------------------------------
   20A Part 5: the H1 sat at y=938, below the fold, while the first thing on
   the page was an 806px paragraph. The lede was pinned to row 3 beside it. */

@media (min-width:1024px){
  .shr-s-masthead h1{ grid-column:1;grid-row:2; }
  .shr-s-masthead .shr-e-crumbs{ grid-column:1;grid-row:1; }
  .shr-s-masthead .shr-e-rule{ grid-column:1;grid-row:3; }
  .shr-s-masthead .shr-e-lede{
    grid-column:2;grid-row:1 / span 4;
    align-self:end;margin-top:0;padding-bottom:10px;
  }
}

/* ---- 6. The boxes -------------------------------------------------------
   20A counted about fifteen box treatments and three different ways of
   presenting the same credential logo. */

/* The stray shadow on twenty-one controls, which is what drew the faint grey
   squares around every dot. */
.shr-dot, .shr-segbar__seg, .shr-pill, .shr-p-more__btn{ box-shadow:none !important; }
body .gform_wrapper.gravity-theme .gform_footer input[type="submit"]{
  border-radius:0;box-shadow:none;
}

/* The dots row sat on top of the client's name and duplicated a control that
   was already there. */
.shr-quotes__dots{ display:none !important; }
.shr-quote figcaption{ margin-top:24px; }

/* The lone elevation on the site. */
.shr-ba__mat, .shr-p-ba figure{ box-shadow:none !important; }

/* One credential treatment, not three. On white the marks stand on the page:
   a logo does not need a box drawn round it, and 20A found Energy Star
   filling fourteen percent of its plate. */
.shr-certs .shr-cert--mark{ border:0;background:none; }
.shr-certs .shr-cert--mark .shr-plate{
  background:none;border:0;border-radius:0;padding:0;
}
/* On the harbour band the ivory ground stays, because a dark mark on navy
   needs one. Rule 16. */
.shr-recognition__bodies .shr-plate{ border-radius:0; }

/* The same four awards were cards on the home page and hairline rows on
   About. They are hairline rows in both places now. */
.shr-recognition__awards{
  display:block;margin-top:40px;
}
.shr-award{
  display:grid;grid-template-columns:minmax(0,1fr);gap:4px;
  border:0;padding:24px 0;
  border-top:1px solid rgba(156,200,236,.28);
}
.shr-recognition__awards .shr-award:last-child{
  border-bottom:1px solid rgba(156,200,236,.28);
}
@media (min-width:768px){
  .shr-award{
    grid-template-columns:minmax(0,1fr) auto;
    align-items:baseline;gap:40px;padding:28px 0;
  }
  .shr-award__body{ margin:0;padding:0;text-align:right; }
}

/* ---- 7. Links that say what they lead to -------------------------------- */

.shr-e-cue::after, .shr-p-lead__cue::after{ content:""; }


/* =============================================================================
   1.55.0. FOUR THINGS QUENTIN SAW.

   RULE 15 IS AMENDED, ON HIS INSTRUCTION. Two components move on their own
   again: the hero frames and the client stories. Both had it in the build
   that won the job. Everything else on this site still holds still, and both
   of these stop for anyone who has asked their machine for reduced motion,
   in a background tab, off screen, and the moment a visitor touches a control.
   ========================================================================== */

/* ---- 1. THE SLIDESHOW AND ITS PROGRESS BAR ------------------------------
   The segment bar now shows how long is left on the frame, which is what
   makes an automatic slideshow feel deliberate rather than restless. It only
   runs on the frame that is timing. */

/* 1.55.1. THIS IS THE ONLY PLACE THE SEGMENTED BAR IS DEFINED.

   It was defined in five places across the stylesheet and 1.55.0 added a
   sixth that set the fill span to width and height 100 percent. The button is
   44px tall for the thumb, so the fill became a 44px white slab sliding
   across the photograph. That is the white bar in Quentin's screenshot and it
   was mine.

   The shape is what it always was: a hairline track with a hairline fill. The
   44px is a tap target, not a bar. */

@keyframes shr-run{ from{transform:scaleX(0)} to{transform:scaleX(1)} }

.shr-segbar{ display:flex;width:100%;align-items:center;gap:12px; }
.shr-segbar__seg{
  position:relative;flex:1;
  min-height:44px;height:44px;
  display:flex;align-items:center;
  padding:0;border:0;background:none !important;
  cursor:pointer;box-shadow:none !important;overflow:visible;
}
/* The track. 3px, the figure the build started with. */
.shr-segbar__seg::before{
  content:"";display:block;width:100%;height:3px;
  background-color:rgba(251,250,247,.35);
}
.shr-segbar--dark .shr-segbar__seg::before{ background-color:rgba(8,36,58,.18); }

/* The fill. Same 3px, sitting exactly on the track, never taller. */
.shr-segbar__seg span{
  position:absolute;left:0;right:0;top:50%;
  height:3px;margin-top:-1.5px;width:auto;
  background-color:var(--shr-ivory);
  transform:scaleX(0);transform-origin:left;
}
.shr-segbar--dark .shr-segbar__seg span{ background-color:var(--shr-harbour); }
.shr-segbar__seg.is-active span{ transform:scaleX(1); }

/* While a frame is running, the fill shows the time left on it. The figures
   are the ones the build opened with: four seconds on the hero, seven on the
   client stories. */
.shr-hero .shr-segbar__seg.is-timing span{
  transform:scaleX(0);
  animation:shr-run 4000ms linear forwards;
}
.shr-quotes__bar .shr-segbar__seg.is-timing span{
  transform:scaleX(0);
  animation:shr-run 7000ms linear forwards;
}
@media (prefers-reduced-motion:reduce){
  .shr-segbar__seg span{ animation:none !important;transform:scaleX(1); }
  .shr-segbar__seg{ cursor:default; }
}

/* The navigation changes colour when the snow frame comes round, so it has to
   change like a dissolve and not like a switch. */
.shr-nav a, .shr-brand__name, .shr-hero__line{
  transition:color .9s ease, text-shadow .9s ease;
}
.shr-header::before{ transition:opacity .9s ease; }

/* ---- 2. THE CLIENT STORIES ----------------------------------------------
   The dots sat on the client's name, the quote had no ground of its own, and
   the section read as a paragraph with controls under it. It is a stage now:
   an opening mark, the quote, the name on its own line, and one control. */

.shr-quotes__stage{
  position:relative;
  display:grid;
  min-height:0;
}
.shr-quote{
  /* position:relative is load bearing. The original rule made every quote
     absolute, which collapsed the stage to nothing and let the control bar
     ride up through the middle of the words. Grid stacking replaces it: all
     eight sit in the same cell, and the stage is as tall as the longest. */
  position:relative;
  grid-area:1 / 1;
  margin:0;
  opacity:0;visibility:hidden;
  transition:opacity .55s ease-in-out, visibility 0s linear .55s;
}
.shr-quote.is-active{
  opacity:1;visibility:visible;
  transition:opacity .55s ease-in-out .25s, visibility 0s linear 0s;
}
/* The outgoing quote is gone before the next one arrives. 18A-2 caught two
   of them overlapping mid-fade, and that .25s is the whole fix. */

.shr-quote blockquote{
  position:relative;margin:0;padding:0;
  border:0;
  text-wrap:balance;
}
.shr-quotes__inner{ text-align:center; }
.shr-quote figcaption{
  margin-top:40px;
  display:flex;flex-direction:column;align-items:center;gap:6px;
}
.shr-quote__name{
  margin:0;
  font-family:var(--shr-font-display);font-size:22px;line-height:1.2;
  color:var(--shr-harbour);
}
@media (min-width:768px){ .shr-quote__name{ font-size:26px; } }
.shr-quote__loc{ margin:0;color:var(--shr-blue); }

/* One control, centred, the width of a paragraph rather than the width of
   the page. Eight segments across 1400px read as eight empty boxes. */
.shr-quotes__bar{
  max-width:420px;margin:48px auto 0;gap:8px;
}


/* ---- 3. BOOK A CONSULTATION, AND THE NUMBER -----------------------------
   A hairline outline button and a 13px telephone number, both ivory on navy,
   were the two quietest things in a band that exists for exactly those two
   things. */

.shr-s-cta-band__actions{
  display:flex;flex-direction:column;align-items:flex-start;gap:28px;margin:36px 0 0;
}
@media (min-width:1024px){
  .shr-s-cta-band__actions{ align-items:flex-end;gap:32px;margin:0; }
}

.shr-cta-primary{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:60px;padding:18px 40px;
  background-color:var(--shr-ivory);color:var(--shr-harbour);
  font-family:var(--shr-font-mono);font-size:13px;font-weight:400;
  letter-spacing:1.68px;text-transform:uppercase;text-decoration:none;
  border:1px solid var(--shr-ivory);border-radius:0;
  transition:background-color .35s ease,color .35s ease,border-color .35s ease;
}
.shr-cta-primary:hover,
.shr-cta-primary:focus-visible{
  background-color:var(--shr-sky);border-color:var(--shr-sky);
  color:var(--shr-harbour);
}
.shr-cta-primary:focus-visible{ outline:2px solid var(--shr-sky);outline-offset:4px; }
@media (min-width:768px){
  .shr-cta-primary{ min-height:64px;padding:20px 48px;font-size:16px; }
}
/* On a light ground the same button is Deep Harbour, so there is one button
   on this site with two grounds rather than four buttons. */
.shr-bg-chalk .shr-cta-primary, .shr-bg-paper .shr-cta-primary,
.shr-bg-ivory .shr-cta-primary, .shr-e-section:not(.shr-bg-harbour) .shr-cta-primary{
  background-color:var(--shr-harbour);color:var(--shr-ivory);border-color:var(--shr-harbour);
}
.shr-bg-chalk .shr-cta-primary:hover, .shr-bg-paper .shr-cta-primary:hover,
.shr-bg-ivory .shr-cta-primary:hover,
.shr-e-section:not(.shr-bg-harbour) .shr-cta-primary:hover{
  background-color:var(--shr-blue);border-color:var(--shr-blue);color:var(--shr-ivory);
}

.shr-cta-call{ display:flex;flex-direction:column;gap:8px;align-items:flex-start; }
@media (min-width:1024px){ .shr-cta-call{ align-items:flex-end; } }
.shr-cta-call__label{
  font-family:var(--shr-font-mono);font-size:12px;letter-spacing:1.68px;
  text-transform:uppercase;color:var(--shr-sky);
}
.shr-cta-call__num{
  font-family:var(--shr-font-display);font-weight:400;
  font-size:30px;line-height:1.1;letter-spacing:.01em;
  color:var(--shr-ivory);text-decoration:none;
  border-bottom:1px solid transparent;
  transition:color .3s ease,border-color .3s ease;
}
@media (min-width:768px){ .shr-cta-call__num{ font-size:38px; } }
.shr-cta-call__num:hover,
.shr-cta-call__num:focus-visible{ color:var(--shr-sky);border-bottom-color:var(--shr-sky); }
.shr-e-section:not(.shr-bg-harbour) .shr-cta-call__label{ color:var(--shr-blue); }
.shr-e-section:not(.shr-bg-harbour) .shr-cta-call__num{ color:var(--shr-harbour); }

/* The header's own button, which had the same problem at the top of every
   page as the band had at the foot of it. */
.shr-header__actions .shr-pill,
.shr-header__actions .shr-e-btn-outline{
  background-color:var(--shr-ivory);color:var(--shr-harbour);
  border-color:var(--shr-ivory);min-height:50px;padding:15px 30px;
}
.shr-header[data-solid="true"] .shr-header__actions .shr-pill{
  background-color:var(--shr-harbour);color:var(--shr-ivory);border-color:var(--shr-harbour);
}
.shr-header__actions .shr-pill:hover{
  background-color:var(--shr-blue);color:var(--shr-ivory);border-color:var(--shr-blue);
}

/* ---- 4. THE FOOTER ------------------------------------------------------
   Four columns of 13px links, a 260px wordmark and three 20px icons. It was
   a sitemap, not a close. */

.shr-footer{ position:relative; }
.shr-footer__rule{
  height:1px;margin-bottom:64px;
  background:linear-gradient(90deg,
    rgba(156,200,236,0) 0%, rgba(156,200,236,.5) 18%,
    rgba(156,200,236,.5) 82%, rgba(156,200,236,0) 100%);
}
@media (min-width:1024px){ .shr-footer__rule{ margin-bottom:88px; } }

.shr-footer__mark img{ width:320px; }
@media (min-width:1024px){ .shr-footer__mark img{ width:360px; } }

.shr-footer__tagline{
  margin-top:28px;font-size:24px;line-height:1.4;max-width:22ch;
  color:var(--shr-ivory);
}
@media (min-width:1024px){ .shr-footer__tagline{ font-size:27px; } }

/* The icons become marks rather than glyphs floating on a field. */
.shr-footer__social{ gap:12px;margin-top:44px;color:var(--shr-sky); }
.shr-footer__social a{
  display:inline-flex;align-items:center;justify-content:center;
  width:52px;height:52px;
  border:1px solid rgba(156,200,236,.34);
  transition:background-color .3s ease,border-color .3s ease,color .3s ease;
}
.shr-footer__social a:hover,
.shr-footer__social a:focus-visible{
  background-color:var(--shr-sky);border-color:var(--shr-sky);color:var(--shr-harbour);
}
.shr-footer__social .shr-icon{ height:22px;width:22px; }

.shr-footer__colhead{
  color:var(--shr-sky);
  padding-bottom:14px;margin-bottom:6px;
  border-bottom:1px solid rgba(156,200,236,.22);
}
.shr-footer__cols ul{ margin-top:14px; }
.shr-footer__cols li{
  font-size:15px;line-height:1.5;margin-bottom:2px;
  color:rgba(251,250,247,.82);
}
.shr-footer__cols a{
  display:block;padding-block:9px;
  border-bottom:1px solid transparent;
  transition:color .3s ease,border-color .3s ease;
}
.shr-footer__cols a:hover,
.shr-footer__cols a:focus-visible{ color:var(--shr-sky); }

@media (min-width:1024px){
  .shr-footer__grid{
    display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);
    column-gap:96px;align-items:start;
  }
}

.shr-footer__base{ border-top:1px solid rgba(156,200,236,.22);padding:28px 20px; }
@media (min-width:768px){ .shr-footer__base{ padding:28px 40px; } }
.shr-footer__baserow{
  max-width:1560px;margin:0 auto;
  display:flex;flex-wrap:wrap;justify-content:space-between;gap:12px 32px;
}
.shr-footer__baserow p{ margin:0;color:rgba(251,250,247,.66); }
.shr-footer__where{ color:rgba(156,200,236,.8) !important; }
@media (max-width:767px){
  .shr-footer__baserow{ justify-content:flex-start;gap:8px; }
}

/* The bar was hidden below 768 because the dots were the phone control. The
   dots are gone, so without this a phone has a swipe and no affordance at
   all: eight stories and nothing to say so. 1.55.0. */
.shr-quotes__bar{ display:flex; }
@media (max-width:767px){
  .shr-quotes__bar{ max-width:300px;margin-top:36px;gap:6px; }
}


/* =============================================================================
   1.56.0. FROM 21A.

   The gate passed: the fill is 3px everywhere. Three things in the brief did
   not, plus what 0f and 0g turned up.
   ========================================================================== */

/* ---- 1. The cross-fade -------------------------------------------------
   0b: 0.45s, and the build opened at 1.2s ease-in-out. A 0.45s change between
   two photographs of a house reads as a jump. This one line at 4840 had been
   quietly overriding the original since 1.47. */

.shr-hero__img{ transition:opacity 1.2s ease-in-out; }
@media (prefers-reduced-motion:reduce){ .shr-hero__img{ transition:none; } }

/* ---- 2. On the snow frame, everything goes dark, not just the words ----
   0b: the cream wordmark and the cream segment fill stayed light on a white
   house. The header already carries both wordmarks; this swaps them. */

html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-brand__mark--light{ opacity:0; }
html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-brand__mark--dark{ opacity:1; }
.shr-brand__mark{ transition:opacity .9s ease; }

.shr-hero[data-ink="dark"] .shr-segbar__seg::before{ background-color:rgba(8,36,58,.28); }
.shr-hero[data-ink="dark"] .shr-segbar__seg span{ background-color:var(--shr-harbour); }
.shr-segbar__seg::before, .shr-segbar__seg span{ transition:background-color .9s ease; }
.shr-hero[data-ink="dark"] .shr-hero__cta{
  background-color:var(--shr-harbour);color:var(--shr-ivory);border-color:var(--shr-harbour);
}

/* ---- 3. The hero bar gets a gutter on a phone --------------------------
   0a: at 390 it ran to x=0, hard against the edge of the screen. */

@media (max-width:767px){
  .shr-hero__band .shr-segbar{ padding-inline:24px;gap:8px; }
}

/* ---- 4. The attribution stops moving -----------------------------------
   0d: the gap between the quote and the client's name ran from 80px to
   235px depending on how long the quote was, so the name jumped up to 155px
   between stories. The quote takes the room it needs and the name sits at the
   foot of the stage, in the same place every time. */

.shr-quotes__stage{ align-items:stretch; }
.shr-quote{ display:grid;grid-template-rows:1fr auto;height:100%; }
.shr-quote blockquote{ align-self:center; }
.shr-quote figcaption{ margin-top:40px;align-self:end; }

/* ---- 5. The footer -----------------------------------------------------
   0f: five service names wrapped to two lines at 1440, the back-to-top button
   covered the base row, and the rail sat over the Get in Touch column. */

@media (min-width:1024px){
  .shr-footer__grid{ grid-template-columns:minmax(0,3fr) minmax(0,9fr);column-gap:72px; }
  .shr-footer__cols{ gap:32px; }
  .shr-footer__cols li{ font-size:16px; }
}
@media (min-width:1280px){
  .shr-footer__cols li{ font-size:16px; }
}

html.shr-at-footer .shr-rail,
html.shr-at-footer .shr-totop,
html.shr-at-footer .shr-to-top,
html.shr-at-footer [class*="totop"],
html.shr-at-footer #ast-scroll-top{
  opacity:0;pointer-events:none;
}
.shr-rail, .shr-totop, .shr-to-top, [class*="totop"], #ast-scroll-top{
  transition:opacity .35s ease;
}

/* ---- 6. Elementor's own entrance animations ----------------------------
   0g: /about-us/ still moved on load at 390. Those are Elementor widget
   entrances, set per widget in the editor. The motion layer in this theme is
   what reveals content, and two systems doing one job is how a section ends
   up arriving twice. */

.elementor-invisible{ visibility:visible !important; }
.elementor-widget.animated,
.elementor-element.animated{
  animation:none !important;
  -webkit-animation:none !important;
}


/* =============================================================================
   1.57.0. FROM 22A.
   ========================================================================== */

/* ---- 1. The header stops changing colour under the visitor --------------
   22A 0d: every 4 seconds the slideshow reaches the snow frame and the
   navigation recoloured, the wordmark swapped and the pill inverted. That is
   the top of the page changing while somebody is reading the middle of it,
   and it is not what the ink switch was for.

   The ink switch stays where it belongs: on the headline, in the middle of
   the frame. The navigation is held by its own scrim, which is always on and
   deep enough for a white sky, so it never has to change at all. */

html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-nav a,
html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-brand__name{
  color:var(--shr-ivory);
  text-shadow:0 1px 4px rgba(8,36,58,.7);
}
html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-brand__mark--light{ opacity:1; }
html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-brand__mark--dark{ opacity:0; }
html[data-hero-ink="dark"] .shr-header::before{ opacity:1; }
.shr-hero[data-ink="dark"] .shr-hero__cta{
  background-color:var(--shr-ivory);color:var(--shr-harbour);border-color:var(--shr-ivory);
}

/* The scrim carries the navigation on every frame now, so it has to hold a
   white sky on its own. At the navigation's height it composites to roughly
   .73 of Deep Harbour, which puts 13px ivory at 6.4:1 over pure white. */
/* 1.57.1. 23A 0b measured the navigation at 3.02:1 over the snow frame, which
   is exactly what .49 of Deep Harbour on a white gable gives. It needs .63 to
   reach 4.5 and this carries .78 at the navigation's own height, which is
   7.5:1, with the whole thing gone by 180px, well above the headline.

   The alternative was to flip the navigation to dark ink on that one frame.
   The mechanism exists and it would work, but it is the thing 23A 0a just
   confirmed is fixed: the top of the page changing colour every twenty
   seconds while somebody reads the middle of it. The scrim does the work and
   nothing moves. */
.shr-header::before{
  /* 1.59.0. The scrim was pushed to .88 over 180px to carry the navigation on
     the snow frame, and at that density it sits on the rooflines. Quentin is
     right that it is covering the houses.

     It comes down to .58 over 128px, which is a top-edge vignette rather than
     a band. Four of the five frames have dark sky or trees behind the
     navigation and read comfortably at this density. The snow frame is the
     one that will not, and the decision on that one is in 28A with figures
     rather than guessed at here. */
  height:128px;
  background:linear-gradient(180deg,
    rgba(8,36,58,.58)  0%,
    rgba(8,36,58,.40) 40%,
    rgba(8,36,58,.18) 70%,
    rgba(8,36,58,0)  100%);
}
/* The type carries its own edge, which costs the photograph nothing. */
.shr-nav a, .shr-brand__name{
  text-shadow:0 1px 3px rgba(8,36,58,.85), 0 2px 12px rgba(8,36,58,.55);
}
.shr-header[data-solid="true"] .shr-nav a,
.shr-header[data-solid="true"] .shr-brand__name{ text-shadow:none; }

/* ---- 2. The About page's buttons ---------------------------------------
   22A 0c: .elementor-kit-4027 a outranks the call to action, so the button
   and the phone number both turned blue and the number read 2.63:1 on navy.
   Specificity, not colour, was the fault. */

.shr-s-cta-band .shr-cta-primary,
.elementor-page .shr-cta-primary,
body .shr-cta-primary{
  background-color:var(--shr-ivory) !important;
  color:var(--shr-harbour) !important;
  border-color:var(--shr-ivory) !important;
}
.shr-s-cta-band .shr-cta-primary:hover,
.elementor-page .shr-cta-primary:hover,
body .shr-cta-primary:hover{
  background-color:var(--shr-sky) !important;border-color:var(--shr-sky) !important;
}
.shr-s-cta-band .shr-cta-call__num,
.elementor-page .shr-cta-call__num,
body .shr-cta-call__num{ color:var(--shr-ivory) !important; }
.shr-s-cta-band .shr-cta-call__label,
.elementor-page .shr-cta-call__label,
body .shr-cta-call__label{ color:var(--shr-sky) !important; }
.shr-s-cta-band .shr-cta-call__num:hover,
body .shr-cta-call__num:hover{ color:var(--shr-sky) !important; }

/* On a light ground the same pair flips, and it has to win there too. */
body .shr-e-section:not(.shr-bg-harbour) .shr-cta-primary{
  background-color:var(--shr-harbour) !important;
  color:var(--shr-ivory) !important;border-color:var(--shr-harbour) !important;
}
body .shr-e-section:not(.shr-bg-harbour) .shr-cta-call__num{ color:var(--shr-harbour) !important; }
body .shr-e-section:not(.shr-bg-harbour) .shr-cta-call__label{ color:var(--shr-blue) !important; }


/* =============================================================================
   1.58.0. FROM 25A, KATHLEEN'S OWN LIST.
   ========================================================================== */

/* ---- Item 3. The logo at the width she asked for ------------------------
   She asked for roughly 4 inches by 1.5. The wordmark is about 5:1, so it
   cannot be both; 25A measured 338.7 x 68, which is 3.5 x 0.7. This takes it
   to 384px, which is 4 inches at 96dpi, and the height follows the artwork.
   Whether she wanted the width or the height is a question for her, and it is
   in the reply. */

@media (min-width:1280px){ .shr-brand__logo{ height:77px; } }
@media (min-width:1440px){ .shr-brand__logo{ height:77px; } }

/* ---- Item 34. The band's heading on /about-us/ --------------------------
   25A: 68px there against 46.4px on every other page, because the Elementor
   kit sets h2 and the band inherits it. One band means one size. */

.shr-s-cta-band h2,
.elementor-page .shr-s-cta-band h2{
  font-size:46.4px !important;line-height:1.08 !important;
}
@media (max-width:767px){
  .shr-s-cta-band h2,
  .elementor-page .shr-s-cta-band h2{ font-size:34px !important; }
}

/* ---- Item 15. The band is one height ------------------------------------
   375px on five pages and 465px on /services/, because that page's paragraph
   runs longer. The lede is capped so the band is the same band everywhere. */

.shr-s-cta-band__lede{ max-width:46ch; }

/* ---- The sequence count loses its leading zero to match --------------- */
.shr-p-seq__num{ display:none; }


/* =============================================================================
   1.60.0. THE FIVE FRAMES, SET FROM 28A'S MEASUREMENTS.

   Not guessed. Every value below is the one the audit arrived at by testing
   candidates and looking at the result. Two things it established that are
   worth writing down, because they explain why earlier attempts failed:

   object-fit:cover only lets an image move in the direction it overflows. At
   1440 only frames 1 and 2 have any vertical room at all, 180px and 60px.
   Frames 3, 4 and 5 fill the height exactly, so a Y value on those does
   nothing. At 390 no frame has vertical room, so the Y values that have sat
   in the mobile rules since the first build have never done anything either.
   Only X matters there.
   ========================================================================== */

/* Frame 1, the glass house at dusk. 180px of vertical room, and this spends
   all of it: the ridge lands at 135px, the deepest setting that still keeps
   the top of the frame clear of roofline. */
.shr-crop-hero-01{ object-position:50% 65%; }

/* Frame 2, Bluebonnet in SPRING from 1.91.0. The snow frame this replaces was
   pulled hard to the top for all the sky it had, because the type on it was
   navy and needed the pale part of the picture. The spring frame is an evening
   scene with lit windows and ivory type, so it wants the house, not the sky.
   Centred, and measured on the rendered page. */
.shr-crop-hero-02{ object-position:50% 50%; }

/* Frame 3, Poetry. Y does nothing. 30% keeps the four navigation links clear
   of the bright sky behind them, which 75% did not: it measured 4.32:1 on
   JOURNAL. The cost is the garage's right pier sitting about 38px outside the
   frame, and an unreadable link is the worse of the two. */
.shr-crop-hero-03{ object-position:30% 50%; }

/* Frame 4, Sandringham at dusk. Already balanced, 20% above the ridge and 20%
   below the base. Left alone. */
.shr-crop-hero-04{ object-position:50% 50%; }

/* Frame 5, Glencanyon at blue hour. The house sits right of centre against
   the forest and the deck ends about 100px clear of the social rail. */
.shr-crop-hero-05{ object-position:75% 50%; }

/* THE THREE INTERIORS. 1.91.1 RE-CROPPED.

   1.91.0 set all three to 50% on the reasoning that centring keeps the middle
   band of the room. Shipped, and the client saw the result: the lower half of
   each band was filled with whatever the camera had nearest it, a counter, a
   run of drawers, a floor. An interior is shot from about counter height, so
   the ROOM is in the upper part of the frame and the crop has to be pulled up
   to find it.

   30% on all three. Chosen from a sweep of 30/40/50/60 scored across all
   three type bands at both hero ratios, and then LOOKED AT with the wordmark,
   the navigation and the headline drawn over the frame at the real positions,
   which is the step 1.91.0 skipped. */

/* Frame 3, Modern Elegance. Unlike the other two this room is shot from
   standing height with the ceiling already in the upper third, so it needs no
   pull: at 50% the run of oak, the island and the stools sit across the middle
   and the dining room and courtyard carry the right. */
.shr-crop-hero-06{ object-position:50% 50%; }

/* Frame 5, Canyon ensuite. At 30% the vanity sits low, the slab wall and the
   window carry the middle, and the wordmark has the pale ceiling. */
.shr-crop-hero-07{ object-position:50% 30%; }

/* Frame 7, Canyon living room. 1.91.2 changed the photograph. Canyon 08
   measured best of every living room tested, 10.08 / 12.81 / 10.46 across the
   three type bands, and it was still the wrong picture: the left 45% of the
   frame was a white stair and a blank wall, so the room sat squeezed into the
   right half. At this ratio a 3:2 source is cropped vertically only, so no
   object-position could move the stair. Numbers were not the whole test.

   Canyon 05 is the long view of the same floor: windows and trees at the
   left, the tufted sofa across the middle, the kitchen and its pendants
   beyond. It fills the frame edge to edge. Measured at 35%: brand 9.64
   (worst block 3.90), nav 12.07 (worst 6.63), headline 9.45 (worst 2.51),
   against a shipping floor of 2.08. At 35% the plank ceiling carries the
   wordmark and the nav, and the sofa and the rug close the bottom. */
.shr-crop-hero-08{ object-position:50% 35%; }

/* The mobile crops. Every one of these is a horizontal decision, because
   there is no vertical room at 390. The Y values are written as 50% so nobody
   tunes a number that cannot do anything. */
@media (max-width:767px){
  .shr-crop-hero-01{ object-position:12% 50%; }  /* centres the vaulted gable */
  .shr-crop-hero-02{ object-position:50% 50%; }  /* symmetric on the porch gable */
  .shr-crop-hero-03{ object-position:42% 50%; }  /* the door between its stone piers */
  .shr-crop-hero-04{ object-position:100% 50%; } /* 26px of play, all of it used */
  .shr-crop-hero-05{ object-position:100% 50%; } /* keeps the deck rail off the edge */
}

/* ---- The snow frame takes the navigation dark --------------------------
   28A Part 3k. I argued against this last night and the numbers have settled
   it. Frame 2 measures 4.02:1 with ivory links and no crop between 0 and 100
   percent moves it past 4.2, because the sky behind them is overcast white.
   Dark ink on that frame measures 12.8:1, but only with the navy overlays
   lifted, so both go together and both only on that frame.

   One frame in five changing ink is worse than none. It is better than a
   navigation nobody can read. */

html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-nav a,
html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-brand__name{
  color:var(--shr-harbour);
  text-shadow:0 1px 3px rgba(247,245,240,.9), 0 2px 12px rgba(247,245,240,.6);
}
html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-brand__mark--light{ opacity:0; }
html[data-hero-ink="dark"] .shr-header:not([data-solid="true"]) .shr-brand__mark--dark{ opacity:1; }
html[data-hero-ink="dark"] .shr-header::before{ opacity:0; }
html[data-hero-ink="dark"] .shr-nav-scrim{ opacity:0; }
.shr-nav-scrim{ transition:opacity .9s ease; }


/* =============================================================================
   1.61.0. TWO FAULTS ON THE HOME PAGE.
   ========================================================================== */

/* ---- 1. THE FOUR PILLARS WERE BLOWN UP TO 76px --------------------------
   This is my rule, from 1.54.0, and it is the same mistake as the portfolio
   grid: a selector written for one thing catching another.

   20A counted five competing section-title sizes on the home page and I set
   them all to 76px with `.shr-opening h2`. The four pillars live inside
   .shr-opening and their words are h2 as of 1.50.0, so Quality, Expertise,
   Craftsmanship and Results were caught by it. Craftsmanship at 76px is about
   600px wide, four of those do not fit across 1400px, and Results and its
   label ran off the right of the screen.

   A pillar is a word in a row of four. It was 36px and it goes back to 36px.
   Section titles keep the 76px, and the rule that gives it to them now says
   which elements it means. */

.shr-opening .shr-pillar h2,
.shr-opening .shr-pillar h3,
.shr-pillar h2, .shr-pillar h3{
  font-size:28px;line-height:1.15;letter-spacing:.01em;margin-top:24px;
}
@media (min-width:768px){
  .shr-opening .shr-pillar h2,
  .shr-opening .shr-pillar h3,
  .shr-pillar h2, .shr-pillar h3{ font-size:36px;margin-top:32px; }
}
@media (min-width:1280px){
  .shr-opening .shr-pillar h2,
  .shr-pillar h2{ font-size:40px; }
}

/* Nothing in that row may push the row wider than the row. A grid column
   will not shrink below its content unless it is told it may. */
.shr-pillars__grid{ max-width:100%; }
.shr-pillars__grid > *{ min-width:0; }
.shr-pillar h2, .shr-pillar h3, .shr-pillar p{
  overflow-wrap:break-word;hyphens:auto;
}
/* Four words, four columns, and the longest of them decides nothing. */
@media (min-width:768px) and (max-width:1199px){
  .shr-pillars__grid{ grid-template-columns:repeat(2,1fr); }
}

/* ---- 2. THE CLIENT STORIES STOP FOR GOOD ON ONE CLICK -------------------
   1.55.0 made a click on a segment take the slideshow over permanently, on
   the reasoning that a visitor who reaches for a control has said they would
   rather drive. On a testimonial that is wrong: one stray click and eight
   stories become one for the rest of the visit, which is exactly what it
   looks like when it is simply broken.

   Both the hero and the stories now restart their timer after an
   interaction, which is what the build did originally. Hovering still pauses
   the stories, and only while the pointer is actually over them. */

@media (hover:none){
  /* A touch screen has no hover, and a phantom one must never pause it. */
  .shr-quotes{ pointer-events:auto; }
}


/* =============================================================================
   1.62.0. FROM 29A, THE MECHANICAL SWEEP.

   The report's own headline is the one that matters: no text is cut off
   anywhere on this site at either width, on 24 of 24 runs. What it did find
   is five real things and a run of orphan rows.
   ========================================================================== */

/* ---- 1. The sticky call bar waits for the visitor -----------------------
   Finding 1, and the only one a visitor meets before they scroll. */

@media (max-width:767px){
  .shr-stickybar{
    transform:translateY(100%);
    transition:transform .45s cubic-bezier(.2,.7,.2,1);
    will-change:transform;
  }
  html.shr-bar-up .shr-stickybar{ transform:translateY(0); }
}
@media (prefers-reduced-motion:reduce){
  .shr-stickybar{ transition:none; }
}

/* ---- 2. The questions rail clears the header ---------------------------
   Finding 2. top:120px against a header whose bottom edge is at 142px, so
   "15 questions" sat behind it every time the rail stuck. */

.shr-l-faq__rail{ top:166px; }
@media (max-width:1023px){ .shr-l-faq__rail{ top:auto; } }

/* Everything else on the site that sticks, measured against the same header
   rather than against a number somebody guessed. */
/* 1.74.5: the split media column is no longer the thing that sticks; the
   figure inside it is. Everything else in this list is unchanged. */
.shr-e-split__media > .shr-e-figure, .shr-c-details, .shr-p-seq__hold, .shr-e-bio__id{
  top:126px;
}

/* ---- 3. The long service button ----------------------------------------
   Finding 3. "Landscaping & outdoor living spaces" is 382px of nowrap type
   in a 350px column, so overflow-x:clip took the right edge off the button.
   A button label is allowed to run to two lines. It is not allowed to be
   sliced. */

/* 1.62.1. Written first as .shr-pill at every phone width, which would have
   let every button on the site wrap to two lines to fix one that overflows.
   That is the same reach that broke the portfolio grid at 1.51.0. It is
   scoped to the button 29A actually measured. */
@media (max-width:767px){
  .shr-l-service-row__more .shr-pill{
    white-space:normal;text-wrap:balance;
    width:100%;max-width:100%;text-align:center;
  }
}

/* ---- 4. The orphan rows ------------------------------------------------
   Findings 6 and 8 to 11. Seven items in a three-up grid leave one alone on
   its own row, which reads as a mistake rather than a set. Wrapped and
   centred, seven read as seven. */

.shr-s-cards--three{
  display:flex;flex-wrap:wrap;justify-content:center;
  align-items:stretch;gap:32px;
}
@media (min-width:768px){
  .shr-s-cards--three > *{ flex:1 1 calc(50% - 16px);min-width:0; }
}
@media (min-width:1024px){
  .shr-s-cards--three > *{ flex:0 1 calc(33.333% - 22px); }
}

/* The room chips, 3 and 5 of them, centred rather than left with a straggler. */
.shr-p-rooms__list{
  display:flex;flex-wrap:wrap;justify-content:center;gap:16px;
}
@media (min-width:600px){ .shr-p-rooms__list > *{ flex:0 1 180px; } }
@media (max-width:599px){ .shr-p-rooms__list > *{ flex:0 1 calc(50% - 8px); } }

/* Poetry's specs and features. 4 in a 3-up and 7 in a 2-up. */
.shr-p-story__specs{ grid-template-columns:repeat(2,minmax(0,1fr)); }
@media (min-width:1024px){ .shr-p-story__specs{ grid-template-columns:repeat(4,minmax(0,1fr)); } }
.shr-p-story__features{ grid-template-columns:minmax(0,1fr); }
@media (min-width:768px){ .shr-p-story__features{ grid-template-columns:repeat(2,minmax(0,1fr)); } }

/* The certification row at 390 was going 2/1/2/2, with one mark stranded in
   the middle. The credential set as type belongs at the end of the row, not
   in the middle of it. */
.shr-certs .shr-cert:not(.shr-cert--mark){ order:2; }
.shr-certs .shr-cert--mark{ order:1; }

/* ---- 5. Poetry's highlight tiles: WITHDRAWN AT 1.62.1 -------------------
   29A called the 279px height difference on Poetry's first row cosmetic, and
   I wrote a rule to level it. Then I read what the rule would be levelling.

   .shr-p-hl is a twelve column editorial grid in which the first tile is
   deliberately large and the others sit around it. .shr-p-hl--even is the
   FALLBACK, used when the opening photograph cannot fill the big frame, and
   Balmoral carries it for exactly that reason. Poetry does not carry it
   because Poetry's opening photograph can.

   So the uneven row is the design, and flattening every .shr-p-hl would have
   turned a feature layout into a plain grid on every project page that has a
   photograph good enough to lead with. Nothing to fix here. */


/* =============================================================================
   1.63.0. NO HOLES IN A ROW.

   The standard on this build: 2026 premium award winning design. A row of
   four that ends with three and a gap where the fourth would be is not a
   layout, it is a leftover. Seven people are seven people, and the row says
   so by being centred.
   ========================================================================== */

.shr-e-people{
  display:flex;flex-wrap:wrap;justify-content:center;
  align-items:flex-start;gap:48px;
}
@media (min-width:640px){
  .shr-e-people{ gap:40px; }
  .shr-e-people > *{ flex:0 1 calc(50% - 20px);min-width:0; }
}
@media (min-width:1024px){
  .shr-e-people > *{ flex:0 1 calc(25% - 30px); }
}
.shr-e-people--wide{ gap:48px; }
@media (min-width:1024px){
  .shr-e-people--wide{ gap:56px; }
  .shr-e-people--wide > *{ flex:0 1 calc(33.333% - 38px); }
}

/* WITHDRAWN AT 1.64.1, BEFORE IT SHIPPED.
   I wrote this at 1.63.0 assuming the team page's bios were laid out the same
   way as the headshot row. They are not. .shr-e-bios is a vertical list, one
   bio under the next with a hairline between them, and .shr-e-bio__row does
   not exist anywhere in this theme. Making it a centred wrap would have
   turned seven stacked bios into a horizontal row of seven columns.

   This is the fourth time in this build that a rule aimed at one component
   has landed on another. The check that caught it is the one that should have
   come first: confirm the selector exists and confirm what it currently does,
   before writing anything that changes it. */

/* ---- The mastheads that open on flat navy ------------------------------
   Four pages open on a plain Deep Harbour block: About, Contact, Journal and
   Questions. Every one of them has photography available and none of them is
   using it. The photographs go on in 30A, page by page, because choosing
   which one belongs on which page is a decision and not a rule.

   What the theme can do is make sure the moment a photograph arrives, the
   masthead is ready for it: full bleed, the grade the hero uses, and the
   heading sitting on the picture rather than beside it. */

.shr-e-masthead--image .shr-e-masthead__inner,
.shr-s-masthead--image .shr-e-masthead__inner{ position:relative;z-index:2; }

/* And where there is genuinely no photograph, navy is not the only answer.
   A hairline rule and the wordmark's own tone give the block something to be
   rather than nothing. */
.shr-e-masthead:not(.shr-s-masthead--image):not(.shr-e-masthead--image){
  background-image:
    radial-gradient(120% 90% at 8% 0%, rgba(156,200,236,.10) 0%, rgba(156,200,236,0) 62%),
    linear-gradient(180deg, rgba(8,36,58,0) 0%, rgba(8,36,58,.35) 100%);
}


/* =============================================================================
   1.64.0. FROM 30A. THE STANDARD IS 2026 PREMIUM AWARD WINNING DESIGN:
   no page opens on a flat block when a photograph could carry it, and no row
   has a hole in it.
   ========================================================================== */

/* ---- 1. The portfolio heading over its photograph ----------------------
   30A measured "Thirty years of work on the North Shore" at 2.91:1 where it
   crosses the lit windows and the pale garage door. It is the first item in
   the navigation. The grade is deepened where the heading sits, left and
   middle, and left alone at the foot where the picture carries itself. */

.shr-s-masthead--image::after{
  background:
    linear-gradient(180deg, rgba(8,36,58,.82) 0%, rgba(8,36,58,.52) 42%, rgba(8,36,58,.80) 100%),
    linear-gradient(90deg, rgba(8,36,58,.70) 0%, rgba(8,36,58,.12) 70%);
}

/* ---- 2. The three holes -------------------------------------------------
   A list that breaks 3/3/1 or 4/1 leaves a hole on the right. Flowing the
   items down columns instead balances them: seven becomes four and three,
   and there is nothing left over. */

.shr-p-story__features{
  display:block;
  columns:1;
}
@media (min-width:768px){
  .shr-p-story__features{ columns:2;column-gap:48px; }
  .shr-p-story__features li{ break-inside:avoid; }
}

body .gform_wrapper.gravity-theme .gfield--type-radio .gfield_radio,
body .gform_wrapper.gravity-theme .gfield--type-checkbox .gfield_checkbox{
  display:block;columns:1;
}
@media (min-width:768px){
  body .gform_wrapper.gravity-theme .gfield--type-radio .gfield_radio,
  body .gform_wrapper.gravity-theme .gfield--type-checkbox .gfield_checkbox{
    columns:2;column-gap:40px;
  }
  body .gform_wrapper.gravity-theme .gchoice{ break-inside:avoid; }
}

/* Four photograph tiles in a three-up strip left one alone with 827px of
   paper beside it. Scoped with :has() to a strip that holds exactly four, so
   strips of three or six are untouched. */
@media (min-width:768px){
  .shr-s-strip:has(> :nth-child(4):last-child){
    grid-template-columns:repeat(2,minmax(0,1fr));
  }
}
@media (min-width:1200px){
  .shr-s-strip:has(> :nth-child(4):last-child){
    grid-template-columns:repeat(4,minmax(0,1fr));
  }
}

/* ---- 3. The team row, levelled ----------------------------------------
   30A: row 2 is 45px out because one name wraps to two lines and the others
   do not. The name reserves two lines whether it needs them or not. */

.shr-e-person__name{ min-height:2.3em; }
@media (min-width:1024px){ .shr-e-person__name{ min-height:2.2em; } }

/* ---- 4. The four mastheads that were flat navy -------------------------
   The photographs arrive through shr_page_hero(), added in
   inc/content-sections.php. This is what receives them: the same treatment
   the portfolio and the project pages already use, so all six pages the top
   navigation reaches now open the same way. */

.shr-j-masthead.shr-s-masthead--image{ position:relative; }
.shr-j-masthead.shr-s-masthead--image .shr-e-masthead__inner{ position:relative;z-index:2; }

/* A masthead carrying a photograph does not also need the flat gradient that
   was put there for the ones that do not. */
.shr-s-masthead--image, .shr-e-masthead--image{ background-image:none; }


/* =============================================================================
   1.65.0. THE STANDARD, APPLIED TO TYPE AND TO THE ONE BUTTON THAT MATTERS.

   2026 premium award winning design for a North Vancouver custom home builder,
   read by an audience mostly over fifty who are spending six and seven
   figures. Two things follow from that and they are the whole of this
   release: reading copy is set large enough to read without effort, and the
   button that starts a conversation is the most inviting thing on the page.
   ========================================================================== */

/* ---- 1. Reading copy, sized for the audience ---------------------------
   Body copy was 16 to 18px. For a reader over fifty on a laptop at arm's
   length, 16px is small and 18px is the floor, not the ceiling. Every
   paragraph of running text on every page goes to 18 on a phone and 20 at
   desktop, with the line height that size needs.

   Scoped to reading text only. Labels, eyebrows, buttons, captions, form
   fields and headings are untouched: a type scale is not a volume knob, and
   the last time a size rule went wide it cut "Results" off the home page. */

.shr-e-prose p, .shr-e-prose li,
.shr-e-article p, .shr-e-article li,
.shr-e-section > .shr-e-inner > p,
.shr-e-section > .shr-e-narrow > p,
.shr-p-story p, .shr-p-story li,
.shr-s-section p, .shr-s-section li,
.shr-opening p, .shr-manifesto p,
.shr-e-bio p, .shr-e-person p,
.shr-s-q__a p, .shr-j-card__excerpt,
.elementor-widget-text-editor p{
  font-size:18px;
  line-height:1.72;
}
@media (min-width:1024px){
  .shr-e-prose p, .shr-e-prose li,
  .shr-e-article p, .shr-e-article li,
  .shr-e-section > .shr-e-inner > p,
  .shr-e-section > .shr-e-narrow > p,
  .shr-p-story p, .shr-p-story li,
  .shr-s-section p, .shr-s-section li,
  .shr-opening p, .shr-manifesto p,
  .shr-e-bio p, .shr-e-person p,
  .shr-s-q__a p, .shr-j-card__excerpt,
  .elementor-widget-text-editor p{
    font-size:20px;
    line-height:1.68;
  }
}
/* A lede is the sentence under a heading and it stays a step above the body. */
.shr-e-lede, .shr-e-lede p, .shr-s-cta-band__lede{
  font-size:20px;line-height:1.6;
}
@media (min-width:1024px){
  .shr-e-lede, .shr-e-lede p, .shr-s-cta-band__lede{ font-size:23px;line-height:1.55; }
}
/* Measure. Twenty pixel type needs a shorter line, not a longer one. */
.shr-e-prose, .shr-e-article, .shr-p-story__body{ max-width:68ch; }

/* ---- 2. Book a Consultation ---------------------------------------------
   It is the reason the site exists. It was 13px of mono in a 60px box, which
   is restrained to the point of being shy. Larger, with a soft inner light so
   it reads as a raised surface rather than a flat rectangle, and a sheen that
   crosses it on hover. The sheen runs only when a visitor points at it, so
   nothing moves on its own. */

.shr-cta-primary,
.shr-header__actions .shr-pill,
.shr-header__actions .shr-e-btn-outline{
  position:relative;overflow:hidden;isolation:isolate;
  font-size:15px;letter-spacing:1.9px;
  box-shadow:0 1px 0 rgba(255,255,255,.55) inset, 0 10px 30px rgba(8,36,58,.18);
}
.shr-cta-primary{ min-height:68px;padding:22px 52px; }
@media (min-width:768px){
  .shr-cta-primary{ min-height:74px;padding:25px 62px;font-size:16px; }
}
.shr-header__actions .shr-pill{ min-height:56px;padding:18px 34px; }

/* The sheen. A narrow band of light that crosses the face once, on hover. */
.shr-cta-primary::after,
.shr-header__actions .shr-pill::after{
  content:"";position:absolute;z-index:-1;top:-50%;bottom:-50%;
  left:-60%;width:40%;
  background:linear-gradient(100deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,.55) 50%,
    rgba(255,255,255,0) 100%);
  transform:skewX(-18deg);
  transition:left .65s cubic-bezier(.2,.7,.2,1);
  pointer-events:none;
}
.shr-cta-primary:hover::after,
.shr-cta-primary:focus-visible::after,
.shr-header__actions .shr-pill:hover::after,
.shr-header__actions .shr-pill:focus-visible::after{ left:120%; }

/* On the navy bands the sheen is light on light, so it lifts rather than
   flashes. On the light grounds it is the reverse. */
.shr-e-section:not(.shr-bg-harbour) .shr-cta-primary::after{
  background:linear-gradient(100deg,
    rgba(156,200,236,0) 0%,
    rgba(156,200,236,.45) 50%,
    rgba(156,200,236,0) 100%);
}
@media (prefers-reduced-motion:reduce){
  .shr-cta-primary::after, .shr-header__actions .shr-pill::after{
    transition:none;display:none;
  }
}
.shr-cta-primary:hover{ transform:translateY(-1px); }
.shr-cta-primary{ transition:background-color .35s ease,color .35s ease,border-color .35s ease,transform .35s ease; }


/* =============================================================================
   1.67.0. THE LIST, DECIDED AND BUILT.
   ========================================================================== */

/* ---- 3. Reading copy: the floor, everywhere ---------------------------
   1.65.0 raised the paragraphs it could name and 32A found sixteen more per
   page that it could not, on the service pages, the FAQ body, the Journal and
   the Elementor sections. This names the containers rather than the
   paragraphs, which is what was missing, and it still excludes labels,
   eyebrows, captions, buttons, form text and headings by only ever selecting
   a <p> or an <li> that is a direct child of a content wrapper. */

.shr-e-section p, .shr-e-section li,
.shr-s-section p, .shr-s-section li,
.shr-l-faq p, .shr-l-faq li,
.shr-s-q__a p, .shr-s-q__a li,
.shr-j-card__excerpt, .shr-j-lead__excerpt,
.elementor-widget-text-editor p, .elementor-widget-text-editor li{
  font-size:18px;line-height:1.72;
}
@media (min-width:1024px){
  .shr-e-section p, .shr-e-section li,
  .shr-s-section p, .shr-s-section li,
  .shr-l-faq p, .shr-l-faq li,
  .shr-s-q__a p, .shr-s-q__a li,
  .shr-j-card__excerpt, .shr-j-lead__excerpt,
  .elementor-widget-text-editor p, .elementor-widget-text-editor li{
    font-size:20px;line-height:1.68;
  }
}
/* The exclusions, restated so the floor cannot reach them. */
.shr-e-eyebrow, .shr-eyebrow, .shr-mono-sm, .shr-e-crumbs,
.shr-p-card__meta, .shr-j-list__meta, .shr-award__body,
.shr-e-person__role, .shr-e-fact__label, .shr-certs__head,
.shr-cta-call__label, .shr-footer__cols li, .shr-footer__legal,
.shr-e-figure figcaption, .shr-p-hl__tag, .shr-quote__loc,
.gform_wrapper p, .gform_wrapper li, .gfield_description{
  font-size:12px !important;
}
/* 1.74.4, rule 15, from REPORT 37D: 32 elements under 16px at 390 wide.
   The links and controls a reader presses reach 16px. The uppercase mono
   column labels and the legal line stay where they are: they are labels set
   with letter spacing, not reading copy, and 16px breaks the type system. */
.shr-footer__cols li{ font-size:16px !important; }
.shr-e-figure figcaption, .shr-p-hl__tag{ font-size:13px !important; }
.gform_wrapper p, .gform_wrapper li{ font-size:16px !important;line-height:1.5; }
.gfield_description{ font-size:14px !important; }

/* ---- 6. The after image fills its column -------------------------------
   Every before-and-after on the site left 200 to 460px of empty paper on the
   right, with the small before inset hanging off the corner into it, because
   the after rendered at its stored pixel width instead of the column's. */

.shr-p-ba, .shr-p-ba figure{ width:100%; }
.shr-p-ba__after, .shr-p-ba__after img,
.shr-p-ba > figure > img{ width:100%;height:auto;display:block; }

/* ---- 11. The story band uses its measure ------------------------------
   448px of empty paper down the left of Poetry, Bluebonnet and Mountain
   Retreat, because the text column was placed rather than centred. */

.shr-p-story__grid{ justify-content:center; }
.shr-p-story__body{ margin-inline:auto; }

/* ---- 12. The enquiry radios, balanced --------------------------------
   Seven options going 3/3/1 with the last one alone. The column rule from
   1.64.0 did not reach them; Gravity Forms sets its own grid with higher
   specificity, so this meets it. */

body .gform_wrapper.gravity-theme .gfield_radio,
body .gform_wrapper.gravity-theme .gfield_checkbox{
  display:block !important;
  grid-template-columns:none !important;
}
@media (min-width:768px){
  body .gform_wrapper.gravity-theme .gfield_radio,
  body .gform_wrapper.gravity-theme .gfield_checkbox{
    columns:2;column-gap:48px;
  }
  body .gform_wrapper.gravity-theme .gchoice{ break-inside:avoid;display:block; }
}

/* ---- 13. The drone video, framed --------------------------------------
   Native controls stay. A custom player is a accessibility liability and a
   maintenance one, and the browser's own is what a visitor already knows.
   What it gets is a frame, so it reads as a considered element rather than a
   raw video tag dropped on the page. */

.shr-e-section video, .shr-s-section video{
  display:block;width:100%;height:auto;
  background-color:var(--shr-harbour);
  border-radius:0;
}
.shr-e-figure:has(> video), figure:has(> video){
  margin:0;background-color:var(--shr-harbour);
}

/* ---- 14. The masthead meets the first section ------------------------
   45px out of step on every page. The masthead's foot now sits on the same
   scale as everything under it. */

@media (min-width:1024px){
  .shr-e-masthead, .shr-s-masthead{ padding-bottom:var(--shr-band-lg); }
}
@media (min-width:768px) and (max-width:1023px){
  .shr-e-masthead, .shr-s-masthead{ padding-bottom:var(--shr-band-md); }
}


/* =============================================================================
   30. THE OFFICE, ON A MAP. 1.68.0
   -----------------------------------------------------------------------------
   What was here was one iframe on the keyless Google endpoint, and 33A found it
   painting a blank grey slab: frame, logo and zoom controls, no tiles. The
   replacement is a panel rather than an embed. The map is a backdrop with its
   pointer events off; the marker is the Shakespeare monogram, sitting on the
   building; and the whole surface is one link to the company's Google listing,
   which is what Quentin asked for on 23 September. A press anywhere opens the
   listing, with its hours, photographs, reviews and directions.

   Every visible control is ours and is a real link, so the panel behaves the
   same whether or not the embed draws.
   ========================================================================== */

.shr-c-map{ position:relative;background:var(--shr-harbour); }

.shr-c-map__surface{
  position:relative;
  width:100%;
  /* 1.68.2: 420 left the phone panel reading half empty once the cluster was
     centred in it. 340 is the height the cluster and its breathing room need. */
  height:340px;
  overflow:hidden;
  background:var(--shr-harbour);
  isolation:isolate;
}
@media (min-width:768px){ .shr-c-map__surface{ height:520px; } }
@media (min-width:1280px){ .shr-c-map__surface{ height:560px; } }

/* The field. No live map and no API key: Google retired the keyless embed, and
   the supported replacement wants a Cloud project and a card on file. The band
   is a designed surface instead, and a press anywhere on it opens the company's
   own Google listing, where the map, the hours, the photographs, the reviews
   and turn by turn directions all are. A fine drafting grid, because this is a
   builder, and a soft light from the north west. */

.shr-c-map__field{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(0deg, rgba(8,36,58,.55) 0%, rgba(8,36,58,0) 55%),
    radial-gradient(120% 95% at 20% 8%, rgba(156,200,236,.20) 0%, rgba(156,200,236,0) 60%),
    radial-gradient(95% 85% at 86% 92%, rgba(0,84,154,.34) 0%, rgba(0,84,154,0) 62%),
    var(--shr-harbour);
}
.shr-c-map__field::before{
  content:"";position:absolute;inset:0;
  background-image:
    linear-gradient(to right, rgba(156,200,236,.10) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(156,200,236,.10) 1px, transparent 1px);
  background-size:72px 72px;
  -webkit-mask-image:radial-gradient(85% 75% at 50% 45%, #000 0%, transparent 78%);
  mask-image:radial-gradient(85% 75% at 50% 45%, #000 0%, transparent 78%);
}
.shr-c-map__field::after{
  content:"";position:absolute;inset:0;
  background-image:
    linear-gradient(to right, rgba(156,200,236,.16) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(156,200,236,.16) 1px, transparent 1px);
  background-size:288px 288px;
  -webkit-mask-image:radial-gradient(85% 75% at 50% 45%, #000 0%, transparent 82%);
  mask-image:radial-gradient(85% 75% at 50% 45%, #000 0%, transparent 82%);
}

/* ---- The marker ---------------------------------------------------------- */

.shr-c-map__pin{
  position:absolute;
  /* 1.68.2. 34B part D7: the cluster was centred on the whole section, which
     left 194px between it and the card and 666px of empty navy to its right,
     and on a phone it sat in the top half of the field with the bottom half
     empty. There is no map under it any more, so there is no point for the stem
     to sit on and no reason to hang the cluster from its tip. It is centred in
     the panel now, and from 900 up it is centred in the space BESIDE the card
     rather than in the section. */
  left:50%;top:50%;
  transform:translate(-50%,-50%);
  display:block;
  z-index:2;
  text-decoration:none;
  /* The hit area is the whole panel, so a press anywhere on the map opens the
     listing, and the badge is what the eye lands on. */
}
.shr-c-map__pin::before{
  /* The press target is the whole map surface, clipped by its overflow. The
     card sits above it on z-index 3, so its own links still work. */
  content:"";position:absolute;
  left:-100vw;top:-100vh;width:300vw;height:300vh;
}
.shr-c-map__badge{
  position:relative;z-index:1;
  /* Centred in the pin box, which is as wide as the cue under it. Without this
     the badge sat left and the stem sat centre, and the two did not line up. */
  margin-inline:auto;
  display:grid;place-items:center;
  width:78px;height:78px;
  border-radius:50%;
  background:var(--shr-ivory);
  box-shadow:0 18px 38px -14px rgba(8,36,58,.55), 0 0 0 1px rgba(8,36,58,.10) inset;
  transition:transform .45s cubic-bezier(.22,1,.36,1), box-shadow .45s ease;
}
@media (min-width:768px){ .shr-c-map__badge{ width:92px;height:92px; } }
.shr-c-map__badge img{
  display:block;width:42px;height:auto;
}
@media (min-width:768px){ .shr-c-map__badge img{ width:50px; } }
.shr-c-map__stem{
  position:relative;z-index:1;
  display:block;margin:-2px auto 0;
  width:0;height:0;
  border-left:9px solid transparent;
  border-right:9px solid transparent;
  border-top:15px solid var(--shr-ivory);
  filter:drop-shadow(0 6px 6px rgba(8,36,58,.28));
  transition:transform .45s cubic-bezier(.22,1,.36,1);
}
.shr-c-map__pin:hover .shr-c-map__badge,
.shr-c-map__pin:focus-visible .shr-c-map__badge{
  transform:translateY(-6px);
  box-shadow:0 26px 48px -14px rgba(8,36,58,.6), 0 0 0 2px var(--shr-blue) inset;
}
.shr-c-map__pin:hover .shr-c-map__stem,
.shr-c-map__pin:focus-visible .shr-c-map__stem{ transform:translateY(-6px); }

/* The band is a link, so it says so. Always legible, never only on hover: a
   press cue a visitor has to discover is not a press cue. */
.shr-c-map__cue{
  position:relative;z-index:1;
  display:block;margin:18px auto 0;
  width:max-content;
  font-family:var(--shr-font-mono);
  text-transform:uppercase;letter-spacing:.16em;
  font-size:12px;line-height:1;
  color:var(--shr-ivory);
  padding-bottom:6px;
  border-bottom:1px solid rgba(251,250,247,.45);
  transition:border-color .4s ease;
}
.shr-c-map__pin:hover .shr-c-map__cue,
.shr-c-map__pin:focus-visible .shr-c-map__cue{ border-bottom-color:var(--shr-sky); }
.shr-c-map__pin:focus-visible{ outline:none; }
.shr-c-map__pin:focus-visible .shr-c-map__badge{ box-shadow:0 0 0 3px var(--shr-sky), 0 26px 48px -14px rgba(8,36,58,.6); }

/* ---- The card ------------------------------------------------------------ */

.shr-c-map__card{
  position:relative;z-index:3;
  background:var(--shr-ivory);
  padding:28px 24px;
  border-top:3px solid var(--shr-blue);
}
.shr-c-map__card .shr-e-eyebrow{ margin:0 0 10px; }
.shr-c-map__card .shr-e-rule{ margin:0 0 16px; }
.shr-c-map__addr{
  margin:0 0 6px;
  font-family:var(--shr-font-display);
  font-size:22px;line-height:1.35;color:var(--shr-harbour);
}
@media (min-width:768px){ .shr-c-map__addr{ font-size:24px; } }
.shr-c-map__park,
.shr-c-map__hours{ margin:0 0 4px;font-size:16px;line-height:1.55;color:var(--shr-slate); }
.shr-c-map__act{
  margin:22px 0 0;
  display:flex;flex-direction:column;gap:12px;
}
.shr-c-map__act .shr-pill{ margin:0;width:100%;justify-content:center; }

@media (min-width:900px){
  /* Card occupies the left 472px of a 1425px section. The centre of what is
     left is 66.5 percent, and that is where the cluster belongs. */
  .shr-c-map__pin{ left:66.5%; }

  /* The card floats over the map's lower left. It is positioned against
     .shr-c-map, not the surface, so the surface's overflow cannot clip it. */
  .shr-c-map__card{
    position:absolute;
    left:clamp(24px,5vw,72px);
    bottom:clamp(24px,4vw,56px);
    width:min(400px,40vw);
    padding:32px 30px;
    box-shadow:0 30px 70px -28px rgba(8,36,58,.55);
  }
}

@media (prefers-reduced-motion:reduce){
  .shr-c-map__badge,
  .shr-c-map__stem,
  .shr-c-map__cue{ transition:none; }
}

/* =============================================================================
   31. AN ENLARGEMENT, TREATED. 1.68.0
   -----------------------------------------------------------------------------
   The project masthead gate drops to 840 x 500 so 24 more project pages open on
   a photograph of the work instead of a navy slab. Below 1200 the file is being
   enlarged, and an enlargement left alone looks like a mistake. Given a slightly
   deeper grade and a fine grain it reads as a treatment, which is the same
   decision a printer makes with a small transparency.
   ========================================================================== */

.shr-s-masthead--soft .shr-s-masthead__bg img{
  filter:saturate(1.04) contrast(1.03);
}
.shr-s-masthead--soft::after{
  background:
    linear-gradient(180deg, rgba(8,36,58,.84) 0%, rgba(8,36,58,.40) 42%, rgba(8,36,58,.84) 100%),
    linear-gradient(90deg, rgba(8,36,58,.66) 0%, rgba(8,36,58,.12) 64%) !important;
}
.shr-s-masthead--soft .shr-s-masthead__bg::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  opacity:.16;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:overlay;
}

/* =============================================================================
   31b. THE LAST THREE FLAT MASTHEADS. 1.68.1
   -----------------------------------------------------------------------------
   THE STANDARD: no page opens on a flat colour block. After the gate drop,
   three project pages still cannot carry a photograph, because the only files
   in the library are 600 x 600, 400 x 600 and, for Seascape, none at all.
   Enlarging those is worse than not, so they get a designed surface instead of
   a colour: the same drafting grid and north west light as the contact band, so
   the page opens on something made rather than on an empty field.

   The selector can only reach a project masthead that has no photograph. A
   masthead with one carries --image and is excluded, so nothing that is already
   working can be touched by this.
   ========================================================================== */

.shr-p-masthead:not(.shr-s-masthead--image){
  position:relative;
  isolation:isolate;
}
.shr-p-masthead:not(.shr-s-masthead--image)::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    linear-gradient(0deg, rgba(8,36,58,.55) 0%, rgba(8,36,58,0) 58%),
    radial-gradient(120% 95% at 18% 6%, rgba(156,200,236,.20) 0%, rgba(156,200,236,0) 60%),
    radial-gradient(95% 85% at 88% 94%, rgba(0,84,154,.32) 0%, rgba(0,84,154,0) 62%);
}
.shr-p-masthead:not(.shr-s-masthead--image) .shr-e-masthead__inner{
  position:relative;z-index:1;
}

/* =============================================================================
   31c. NO MASTHEAD OPENS ON A FLAT COLOUR. 1.68.2
   -----------------------------------------------------------------------------
   34B found /what-our-clients-say/ opening on a flat navy block, and it was not
   alone: page-testimonials.php, page-why-shakespeare-homes.php and
   page_archive.php all passed null where every other template passes a
   photograph. All three now pass one, so the real fix is a featured image on
   each page.

   This is the net under that. Any masthead anywhere on the site that ends up
   without a photograph gets the designed surface instead of a colour, so THE
   STANDARD holds even on a page nobody remembered to give an image to. A
   masthead WITH a photograph carries --image and is excluded, so this cannot
   reach anything that is already right.
   ========================================================================== */

.shr-s-masthead:not(.shr-s-masthead--image),
.shr-e-masthead:not(.shr-s-masthead--image){
  position:relative;
  isolation:isolate;
}
.shr-s-masthead:not(.shr-s-masthead--image)::before,
.shr-e-masthead:not(.shr-s-masthead--image)::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    linear-gradient(0deg, rgba(8,36,58,.55) 0%, rgba(8,36,58,0) 58%),
    radial-gradient(120% 95% at 18% 6%, rgba(156,200,236,.20) 0%, rgba(156,200,236,0) 60%),
    radial-gradient(95% 85% at 88% 94%, rgba(0,84,154,.32) 0%, rgba(0,84,154,0) 62%);
}
.shr-s-masthead:not(.shr-s-masthead--image) .shr-e-masthead__inner,
.shr-e-masthead:not(.shr-s-masthead--image) .shr-e-masthead__inner{
  position:relative;z-index:1;
}

/* =============================================================================
   31d. THE CERTIFICATION ROW, AND THE SPLIT BANDS. 1.68.3
   -----------------------------------------------------------------------------
   Two findings from 34C part G.

   The certification row wrapped four then three, because the flex basis was 25
   percent at every width from 768 up. Seven marks in a 1400px band have 200px
   each, which is room enough for a plate, so from 1200 they share one row and
   the wrap disappears. Below that they stay a centred wrap, which never shows a
   hole whatever the count.

   The split bands left up to 970px of empty column on the service pages,
   because the copy runs long and the photograph is one fixed height at the top
   of its track. The media column is sticky now, so the photograph travels down
   beside the copy instead of stranding the right half of the band. It releases
   at the end of the section, and below 1024 the columns stack and none of this
   applies.
   ========================================================================== */

@media (min-width:1200px){
  .shr-certs__grid{ gap:24px; }
  .shr-certs__grid > *{ flex:1 1 calc(16.6666% - 20px);max-width:calc(16.6666% - 20px);min-width:0; }
  .shr-certs .shr-plate--lg{ padding:16px 14px; }
  .shr-certs .shr-plate--lg .shr-plate__mark{ max-height:58px; }
  .shr-certs .shr-plate--word{ font-size:12px;letter-spacing:.10em;line-height:1.45;text-align:center; }
}

@media (min-width:1024px){
  /* 1.74.5, from REPORT 37E. THIS DECLARATION WAS THE VOID.

     align-self:start on the grid ITEM overrides align-items on the grid
     CONTAINER, whatever the container says. So 1.74.4 stretched the container,
     the item ignored it, the column stayed exactly as tall as the photograph,
     and the sticky figure inside it had no track to travel in. Both voids
     measured IDENTICAL to the release before it, 1,435px and 641px, to the
     pixel. The fix shipped and was cancelled by one word one level up.

     The column stretches. The figure travels inside it. See section 44. */
  .shr-e-split__media{
    position:static;
    align-self:stretch;
  }
  .shr-e-split__media:has(> figure:only-child) { max-height:none; }
}

/* =============================================================================
   31e. THE BUTTON IN THE CLIENT'S OWN COPY. 1.68.4
   -----------------------------------------------------------------------------
   shr_sections_restyle_buttons() turns a standalone CONTACT US link into
   <a class="shr-e-btn-outline">, and until now the only CSS carrying that class
   targeted .elementor-button. A bare anchor got nothing, so the most important
   control on a service page rendered as an underlined link in running copy.
   Quentin, 24 September: "the contact us button as you scroll needs to be a lot
   more appealing and organized and attractive looking".

   It is the site's primary button now, the same object as the one in the
   closing band, which means this site has one call to action with two grounds
   rather than four different buttons.
   ========================================================================== */

a.shr-e-btn-outline{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:60px;padding:18px 40px;margin:8px 0 0;
  background-color:var(--shr-harbour);color:var(--shr-ivory);
  font-family:var(--shr-font-mono);font-size:13px;font-weight:400;
  letter-spacing:1.68px;text-transform:uppercase;text-decoration:none;
  border:1px solid var(--shr-harbour);border-radius:0;
  transition:background-color .35s ease,color .35s ease,border-color .35s ease;
}
@media (min-width:768px){
  a.shr-e-btn-outline{ min-height:64px;padding:20px 48px;font-size:16px; }
}
a.shr-e-btn-outline:hover,
a.shr-e-btn-outline:focus-visible{
  background-color:var(--shr-blue);border-color:var(--shr-blue);color:var(--shr-ivory);
}
a.shr-e-btn-outline:focus-visible{ outline:2px solid var(--shr-sky);outline-offset:4px; }

/* On Deep Harbour the same button inverts, as .shr-cta-primary does. */
.shr-bg-harbour a.shr-e-btn-outline,
.shr-e-masthead a.shr-e-btn-outline{
  background-color:var(--shr-ivory);border-color:var(--shr-ivory);color:var(--shr-harbour);
}
.shr-bg-harbour a.shr-e-btn-outline:hover,
.shr-bg-harbour a.shr-e-btn-outline:focus-visible,
.shr-e-masthead a.shr-e-btn-outline:hover,
.shr-e-masthead a.shr-e-btn-outline:focus-visible{
  background-color:var(--shr-sky);border-color:var(--shr-sky);color:var(--shr-harbour);
}

/* A folded call to action arrives as an h3 and a button at the foot of the
   section above it. It gets air, so it reads as an invitation rather than as
   another paragraph. */
.shr-e-section h3 + a.shr-e-btn-outline,
.shr-e-split__copy h3 + a.shr-e-btn-outline{ margin-top:14px; }
.shr-e-section :where(p, div) > a.shr-e-btn-outline:only-child{ margin-top:4px; }

/* =============================================================================
   31f. THREE THINGS 34D MEASURED. 1.68.5
   -----------------------------------------------------------------------------
   1. The portfolio's last row. 35 cards over three columns leaves a row of two
      and an empty cell, and that empty cell is the last thing a visitor sees on
      the page. The grid runs on six columns now with each card spanning two, so
      a remainder of two gives two cards of three columns each and a remainder of
      one gives a single full width card. The row always fills, at any project
      count, without anyone having to keep the number divisible by three.

   2. Card intros ran 1216px wide, about 120 characters a line. THE STANDARD
      says reading copy is large enough to read without effort, and a 120
      character line is twice what an eye tracks comfortably. Capped at the
      measure every other reading column on this site uses.

   3. The breadcrumb was centred inside a left aligned masthead.
   ========================================================================== */

@media (min-width:1100px){
  .shr-p-grid{ grid-template-columns:repeat(6,minmax(0,1fr)); }
  .shr-p-grid > *{ grid-column:span 2; }
  .shr-p-grid:has(> *:nth-child(3n+2):last-child) > *:nth-last-child(-n+2){ grid-column:span 3; }
  .shr-p-grid:has(> *:nth-child(3n+1):last-child) > *:last-child{ grid-column:span 6; }
}

.shr-e-section .shr-e-lede,
.shr-s-section .shr-e-lede{
  max-width:var(--shr-measure-body);
}
.shr-e-section .shr-e-lede :where(p),
.shr-s-section .shr-e-lede :where(p){ max-width:var(--shr-measure-body); }

.shr-s-masthead .shr-e-crumbs,
.shr-e-masthead .shr-e-crumbs{ justify-content:flex-start; }

/* =============================================================================
   31g. THE TWO LOGO ROWS, AS ONE SET EACH. 1.68.6
   -----------------------------------------------------------------------------
   Quentin, 24 September, with screenshots of both rows: "make these logos much
   bigger and more attractive looking without losing the quality of each logo",
   and for the awards row, "get creative and make a design for Ovation Awards so
   it doesn't look off from the rest".

   Both rows had the same two faults. The marks drew at 46 to 58px inside plates
   sized to whatever the file happened to be, so six or four different files
   read as six or four different objects at six or four different weights. And
   the plates were doing the opposite of their job: an ivory chip on a chalk
   band is a visible white rectangle, and a transparent mark beside a
   white-ground mark makes the white ground look like a mistake.

   The answer for both rows is the same. Every mark sits on a chip of exactly
   the same size, so the row reads as a row of credentials rather than as a
   collection of files, and the mark inside draws to a common optical height
   rather than a common box. Nothing is stretched: max-height with auto width
   means each logo keeps its own proportions and its own colours, which is
   rule 16.

   Ovation Awards has no mark in this library free of a year, so rule 14 forbids
   using one. It gets the same chip as the other three, with its name set in the
   site's display face between two hairlines, which is how an award is set on a
   certificate. Four chips, one row, one object.
   ========================================================================== */

/* ---- The certification row, on chalk ------------------------------------ */

.shr-certs .shr-cert{ min-height:0; }
.shr-certs .shr-plate,
.shr-certs .shr-plate--lg{
  width:100%;
  min-height:128px;
  padding:22px 20px;
  background:#ffffff;
  border:1px solid rgba(8,36,58,.07);
  border-radius:2px;
  box-shadow:0 10px 26px -20px rgba(8,36,58,.35);
}
.shr-certs .shr-plate__mark,
.shr-certs .shr-plate--lg .shr-plate__mark{
  max-height:74px;
  max-width:100%;
  width:auto;height:auto;
  object-fit:contain;
}
@media (min-width:768px){
  .shr-certs .shr-plate,
  .shr-certs .shr-plate--lg{ min-height:140px;padding:24px 22px; }
  .shr-certs .shr-plate__mark,
  .shr-certs .shr-plate--lg .shr-plate__mark{ max-height:82px; }
}
@media (min-width:1200px){
  .shr-certs .shr-plate,
  .shr-certs .shr-plate--lg{ min-height:148px;padding:24px 18px; }
  .shr-certs .shr-plate__mark,
  .shr-certs .shr-plate--lg .shr-plate__mark{ max-height:88px; }
}
/* The band was carrying more empty height than the marks it held. */
.shr-certs{ padding-top:72px;padding-bottom:72px; }
@media (min-width:768px){ .shr-certs{ padding-top:96px;padding-bottom:96px; } }

/* ---- The awarding bodies row, on harbour -------------------------------- */

@media (min-width:768px){
  /* Four equal chips. A basis of 25 percent with a matching max-width rather
     than flex:1 1 0, so a long word inside one chip can never push the row
     past the container. It still wraps rather than overflowing if it has to. */
  .shr-recognition__bodies{ gap:24px;align-items:stretch; }
  .shr-recognition__bodies > *{
    flex:1 1 calc(25% - 18px);
    max-width:calc(25% - 18px);
    min-width:0;
  }
}
.shr-recognition__bodies .shr-plate{
  width:100%;
  min-height:120px;
  padding:20px 18px;
  background:var(--shr-ivory);
  border:1px solid rgba(251,250,247,.16);
  border-radius:2px;
}
.shr-recognition__bodies .shr-plate__mark{
  max-height:68px;max-width:100%;width:auto;height:auto;object-fit:contain;
}
@media (min-width:768px){
  .shr-recognition__bodies .shr-plate{ min-height:136px;padding:22px 20px; }
  .shr-recognition__bodies .shr-plate__mark{ max-height:78px; }
}
@media (min-width:1200px){
  .shr-recognition__bodies .shr-plate{ min-height:148px; }
  .shr-recognition__bodies .shr-plate__mark{ max-height:86px; }
}

/* Ovation Awards, set as a certificate rather than left as a caption. */
.shr-recognition__bodies .shr-plate--word,
.shr-recognition__bodies .shr-plate--word.shr-mono-sm{
  background:var(--shr-ivory);
  border:1px solid rgba(251,250,247,.16);
  border-radius:2px;
  color:var(--shr-harbour);
  font-family:var(--shr-font-display) !important;
  font-weight:400;
  font-size:22px !important;
  line-height:1.15;
  letter-spacing:.01em !important;
  text-transform:none !important;
  text-align:center;
  padding:20px 18px !important;
  min-height:120px;
  flex-direction:column;
  gap:10px;
}
@media (min-width:768px){
  .shr-recognition__bodies .shr-plate--word,
  .shr-recognition__bodies .shr-plate--word.shr-mono-sm{
    min-height:136px;font-size:25px !important;padding:22px 20px !important;
  }
}
@media (min-width:1200px){
  .shr-recognition__bodies .shr-plate--word,
  .shr-recognition__bodies .shr-plate--word.shr-mono-sm{
    min-height:148px;font-size:27px !important;
  }
}
/* Two hairlines in the company blue, above and below the name, the way an
   award is set on a certificate. The old rule drew one line in sky over the
   dark band and is replaced here. */
.shr-recognition__bodies .shr-plate--word::before,
.shr-recognition__bodies .shr-plate--word::after{
  content:"";display:block;position:static;
  width:52px;height:1px;left:auto;right:auto;top:auto;
  background:var(--shr-blue);opacity:.55;
  margin:0 auto;
}

/* =============================================================================
   31h. THE CONTACT FORM'S LABELS, AND THE PHONE SPLIT. 1.68.7
   -----------------------------------------------------------------------------
   34E, on /contact/: the form labels and the office labels are 12px, which THE
   STANDARD calls out by name for an audience mostly over fifty. The type floor
   at 1.67.0 held every label at 12px deliberately, and that is right for an
   eyebrow above a section heading. It is not right for the label above a field
   somebody has to fill in, or for the word Address above the address. Those two
   go up.

   And on a phone, 34E found every service page's photograph sitting 126px below
   its copy, which is closer to the NEXT section's heading than to its own. The
   gap between the two halves of a split is the cause. Tightened, so a
   photograph reads as belonging to the words above it.
   ========================================================================== */

body .gform_wrapper.gravity-theme .gfield_label,
body .gform_wrapper.gravity-theme legend.gfield_label{
  font-size:15px;
  letter-spacing:.10em;
  line-height:1.5;
}
body .gform_wrapper.gravity-theme .gfield_required .gfield_required_text{ font-size:15px; }
body .gform_wrapper.gravity-theme .gform-field-label--type-sub{ font-size:14px;letter-spacing:.08em; }

.shr-c-list dt{ font-size:14px;letter-spacing:.10em;line-height:1.7; }
.shr-c-list dd{ font-size:17px; }

@media (max-width:1023px){
  .shr-e-split{ gap:24px; }
}
@media (max-width:767px){
  .shr-e-split{ gap:20px; }
}

/* =============================================================================
   31i. THE PHONE PHOTO THAT SAT IN THE NEXT SECTION. 1.68.8
   -----------------------------------------------------------------------------
   34E and 34F both measured it: at 390 every split band's photograph sits about
   126px below where it belongs and runs roughly 62px into the section beneath,
   so it reads as the next service's picture. Tightening the grid gap in 1.68.7
   did not move it, which rules the gap out: a gap cannot make a box overlap the
   thing after it. Only a transform or a sticky position can.

   Rather than guess which, this removes both at phone and tablet width. If the
   cause is a reveal transform that never settles, transform:none settles it. If
   it is the sticky media column from 31d leaking below its breakpoint,
   position:static ends it. If it is neither, nothing here changes anything.

   A rule that can only ever remove displacement is the right shape of fix for a
   fault that cannot be reproduced from here. The cost is the subtle lift on
   those figures on a phone, which nobody asked for and which is not worth a
   photograph appearing under the wrong heading.
   ========================================================================== */

@media (max-width:1023px){
  .shr-e-split__media,
  .shr-e-split__media > .shr-e-figure,
  .shr-e-split__media > figure{
    position:static !important;
    top:auto !important;
    bottom:auto !important;
    transform:none !important;
    margin-top:0;
    margin-bottom:0;
  }
  .shr-e-split__media img{ transform:none !important; }
}

/* =============================================================================
   34. THE SERVICES SHORTCUT IN THE HEADER. 1.69.0
   -----------------------------------------------------------------------------
   Quentin, 23 September: a visitor should not have to open Services and then
   hunt for the one thing they came for.

   The panel opens on hover and on keyboard focus, in CSS alone. No script runs
   it, so it cannot break if a script fails, and a keyboard user reaches every
   link by tabbing. The Services label is still a link to /services/, so on a
   touch screen with no hover nothing is lost and nothing changes. That is the
   whole safety argument for adding a nav component on send night: if every new
   rule below were deleted, the header would behave exactly as it did before.

   The panel is a solid Ivory card in both header states, because the header is
   transparent over the hero and solid everywhere else, and a menu that changes
   colour underneath you is not calm. Rows are 44px, labels are 15px sentence
   case rather than 13px uppercase: this is reading, not chrome.
   ========================================================================== */

.shr-nav__item{ position:relative;display:inline-flex;align-items:center; }

/* The bridge. Without it the panel closes in the gap between the label and the
   card, and the visitor has to chase it. */
.shr-nav__item::after{
  content:"";position:absolute;left:-16px;right:-16px;top:100%;height:18px;
  display:block;
}

.shr-nav__panel{
  position:absolute;
  top:calc(100% + 16px);
  left:50%;
  transform:translateX(-50%) translateY(-6px);
  z-index:60;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .28s ease, transform .28s cubic-bezier(.22,1,.36,1), visibility 0s linear .28s;
}
.shr-nav__item:hover > .shr-nav__panel,
.shr-nav__item:focus-within > .shr-nav__panel{
  opacity:1;visibility:visible;pointer-events:auto;
  transform:translateX(-50%) translateY(0);
  transition:opacity .28s ease, transform .28s cubic-bezier(.22,1,.36,1), visibility 0s;
}

.shr-nav__panelinner{
  display:grid;
  grid-template-columns:repeat(2,minmax(238px,1fr));
  gap:2px 32px;
  padding:22px 30px;
  background:var(--shr-ivory);
  border-top:3px solid var(--shr-blue);
  box-shadow:0 30px 70px -26px rgba(8,36,58,.5), 0 0 0 1px rgba(8,36,58,.06);
}

/* These are links inside .shr-nav, so they arrive carrying the chrome styling:
   13px, uppercase, ivory, with a text shadow for the hero. All of it is undone
   here, at the same specificity or higher. */
.shr-nav a.shr-nav__sub,
.shr-header[data-solid="true"] .shr-nav a.shr-nav__sub{
  display:flex;align-items:center;
  min-height:44px;
  padding:6px 10px;
  margin:0 -10px;
  white-space:nowrap;
  font-family:var(--shr-font-sans);
  font-size:15px;
  font-weight:400;
  letter-spacing:.01em;
  text-transform:none;
  text-shadow:none;
  color:var(--shr-harbour);
  border-radius:2px;
  transition:background-color .2s ease,color .2s ease;
}
.shr-nav a.shr-nav__sub:hover,
.shr-nav a.shr-nav__sub:focus-visible{
  color:var(--shr-blue);
  background:var(--shr-chalk);
}
.shr-nav a.shr-nav__sub:focus-visible{ outline:2px solid var(--shr-sky);outline-offset:-2px; }

/* All Services closes the list, set apart from the ten it summarises.
   The data-solid variant is repeated here on purpose: without it the rule
   above wins on specificity and the label stays sentence case. */
.shr-nav a.shr-nav__sub:last-child,
.shr-header[data-solid="true"] .shr-nav a.shr-nav__sub:last-child{
  grid-column:1 / -1;
  margin-top:8px;
  padding-top:14px;
  border-top:1px solid rgba(8,36,58,.12);
  border-radius:0;
  font-family:var(--shr-font-mono);
  font-size:12px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--shr-blue);
}

@media (prefers-reduced-motion:reduce){
  .shr-nav__panel{ transition:opacity .01s linear, visibility 0s linear .01s;transform:translateX(-50%); }
  .shr-nav__item:hover > .shr-nav__panel,
  .shr-nav__item:focus-within > .shr-nav__panel{ transform:translateX(-50%); }
}

/* ---- The same shortcut in the phone drawer ------------------------------ */

.shr-mobile__sub{
  display:block;
  margin:2px 0 14px;
  padding-left:2px;
}
.shr-mobile__list .shr-mobile__sub a{
  min-height:44px;
  padding:4px 0;
  font-family:var(--shr-font-sans);
  font-size:16px;
  line-height:1.35;
  letter-spacing:.01em;
  color:rgba(251,250,247,.72);
  /* The drawer staggers its four main links with --i. These carry no --i, so
     they are shown outright rather than inheriting a transform that never
     runs. */
  transform:none;
  opacity:1;
  transition:color .2s ease;
}
.shr-mobile__list .shr-mobile__sub a:hover,
.shr-mobile__list .shr-mobile__sub a:focus-visible{ color:var(--shr-ivory); }

/* =============================================================================
   35. KATHLEEN'S 24 SEPTEMBER NOTES. 1.70.0
   -----------------------------------------------------------------------------
   Two of her five are markup and live in front-page.php. These two are here.

   The header's Book a Consultation loses its box. It keeps the header's own
   type and a rule beneath it, so it still reads as the one thing to press
   without competing with the wordmark and the nav. The hit area stays 44px.
   Only this control changes: the closing band on every page and the sticky bar
   on a phone keep their solid buttons, which is where somebody actually decides
   to book, and which Quentin asked to make MORE prominent on 23 September.
   There is no conflict between those two instructions once you see that they
   are about different controls.

   And the hero band loses the row that held View Our Work. On a phone that band
   was pinned from 74 percent of the screen to the bottom with a solid Deep
   Harbour ground, which was right when it held a button and a bar. With only
   the bar left it would have been a navy block two thirds empty, so the band
   hugs its content and fades out instead of stopping on a hard edge.
   ========================================================================== */

.shr-header__cta--plain{
  display:inline-flex;align-items:center;
  min-height:44px;padding:11px 0;
  font-family:var(--shr-font-sans);font-size:13px;
  letter-spacing:.14em;text-transform:uppercase;text-decoration:none;
  white-space:nowrap;
  background:none;border:0;border-radius:0;
  border-bottom:1px solid rgba(251,250,247,.55);
  color:var(--shr-ivory);text-shadow:0 1px 3px rgba(8,36,58,.45);
  transition:color .3s ease,border-color .3s ease;
}
.shr-header[data-solid="true"] .shr-header__cta--plain{
  background:none;
  color:var(--shr-harbour);text-shadow:none;
  border:0;border-bottom:1px solid var(--shr-blue);
}
.shr-header__cta--plain:hover,
.shr-header__cta--plain:focus-visible,
.shr-header[data-solid="true"] .shr-header__cta--plain:hover,
.shr-header[data-solid="true"] .shr-header__cta--plain:focus-visible{
  background:none;
  color:var(--shr-sky);
  border-bottom-color:var(--shr-sky);
}
.shr-header[data-solid="true"] .shr-header__cta--plain:hover,
.shr-header[data-solid="true"] .shr-header__cta--plain:focus-visible{
  color:var(--shr-blue);border-bottom-color:var(--shr-blue);
}
.shr-header__cta--plain:focus-visible{ outline:2px solid var(--shr-sky);outline-offset:4px; }

@media (max-width:767px){
  .shr-hero__band{
    top:auto;
    bottom:calc(var(--shr-sticky-h) + env(safe-area-inset-bottom));
    height:auto;
    min-height:0;
    padding:56px 24px 18px;
    background-color:transparent;
    background-image:linear-gradient(to top, rgba(8,36,58,.95) 0%, rgba(8,36,58,.62) 46%, rgba(8,36,58,0) 100%);
  }
  .shr-hero__band .shr-segbar{ margin-bottom:0; }
}

/* =============================================================================
   36. KATHLEEN'S 24 SEPTEMBER LIST, PART 2. BATCH ONE, THE SITEWIDE CHROME
   1.71.0
   -----------------------------------------------------------------------------
   She wrote "same as previous" eleven times, which is the tell: most of this
   round is eight patterns repeated across fifteen pages. Fixing them here fixes
   them everywhere at once, and that is what makes the rest of the list
   tractable in a day.
   ========================================================================== */

/* ---- 36.1 The logo, back to the size she asked for -----------------------
   Kathleen: "the Shakespeare Logo seems to have reverted back to its original
   size and it's the 4 inch larger size previously noted." */

.shr-brand__logo{ height:46px; }
@media (min-width:1024px){ .shr-brand__logo{ height:62px; } }
@media (min-width:1440px){ .shr-brand__logo{ height:76px; } }

/* ---- 36.2 The four pillars -----------------------------------------------
   "centered, larger font size, remove the lines above, and the smaller text
   below." The hairline and the sub line are out of the markup; this is the
   centring and the size. */

.shr-pillars__grid{ text-align:center; }
.shr-pillar{ text-align:center;align-items:center; }
.shr-pillar h2{
  font-size:clamp(28px,4.4vw,46px);
  line-height:1.1;
  margin:0;
  text-align:center;
}
@media (min-width:1024px){ .shr-pillar h2{ font-size:clamp(34px,3.2vw,52px); } }

/* ---- 36.3 Client Stories -------------------------------------------------
   "Can this section be in navy? And the title text larger?" */

.shr-quotes{ background-color:var(--shr-harbour);color:var(--shr-ivory); }
.shr-quotes .shr-e-eyebrow,
.shr-quotes .shr-mono-sm{ color:var(--shr-sky);font-size:22px;letter-spacing:.10em; }
@media (min-width:768px){
  .shr-quotes .shr-e-eyebrow,
  .shr-quotes .shr-mono-sm{ font-size:28px; }
}
.shr-quotes blockquote{ color:var(--shr-ivory); }
.shr-quotes figcaption,
.shr-quotes figcaption *{ color:rgba(251,250,247,.78); }

/* ---- 36.4 Journal cards --------------------------------------------------
   Category and read time are out of the markup. Titles go up, and Read becomes
   the same small blue link the rest of the site uses. */

.shr-j-card__title{ font-size:24px;line-height:1.25; }
@media (min-width:768px){ .shr-j-card__title{ font-size:28px; } }
@media (min-width:1280px){ .shr-j-card__title{ font-size:30px; } }

/* ---- 36.5 The footer mark and the social icons ---------------------------
   "Can the SHR logo be replaced with this one below and be centered above the
   We live here text. And can the boxes around the IG, LI and Youtube icons be
   removed too? I like the icons!" */

.shr-footer__mark--monogram{ display:flex;justify-content:center; }
.shr-footer__mark--monogram img{
  width:auto;height:92px;max-width:100%;display:block;
}
@media (min-width:768px){ .shr-footer__mark--monogram img{ height:110px; } }
.shr-footer__brand{ text-align:center; }
.shr-footer__tagline{ text-align:center;margin-left:auto;margin-right:auto; }
.shr-footer__social{ justify-content:center; }
.shr-footer__social a{
  background:none !important;
  border:0 !important;
  border-radius:0 !important;
  box-shadow:none !important;
  width:auto;height:auto;
  padding:10px;
  min-width:44px;min-height:44px;
  display:inline-flex;align-items:center;justify-content:center;
}
.shr-footer__social a svg{ width:22px;height:22px; }

/* ---- 36.6 The white boxes around the logos -------------------------------
   "I don't like these white boxes around each of the organization logos. Could
   those be removed please? Same for the other logos in the section below."

   Four of the six certification files and three of the four award files carry
   an opaque white ground baked into the image, which is why the plates were
   there in the first place: rule 16 says a logo is shown in its own colours,
   and a white-ground file knocked out on Deep Harbour is unreadable.

   So the plate is not hidden, it is made unnecessary. On a light ground,
   multiply blending drops a white ground out of the file completely and leaves
   the artwork untouched. The certification row already sits on chalk. The
   awarding bodies row moves onto its own chalk strip at the foot of the navy
   band, which is what the plates were standing in for. Every mark now sits on
   one continuous light field with no box of any kind, in its own colours. */

.shr-certs .shr-plate,
.shr-certs .shr-plate--lg,
.shr-recognition__bodies .shr-plate{
  background:none !important;
  border:0 !important;
  border-radius:0 !important;
  box-shadow:none !important;
  padding:0 !important;
  min-height:0 !important;
}
/*
 * 1.71.2. Two goes at multiply did not clear the certification row, so the
 * blend approach is abandoned rather than debugged further. mix-blend-mode
 * composites against the nearest stacking context and GSAP puts a transform on
 * every reveal-item, which makes that context unpredictable across the row.
 *
 * The ground is matched to the files instead. Four of these six logos carry an
 * opaque pure white rectangle baked into the image, so a pure white ground
 * makes the rectangle disappear by definition. No blending, no stacking
 * context, nothing to go wrong. Both logo grounds are white now and the marks
 * sit on them with nothing around them.
 *
 * The better fix is transparent source files, and those are worth producing
 * before launch so these marks also work on a dark ground. This is the fix that
 * is right today.
 */
.shr-certs .shr-plate__mark,
.shr-recognition__bodies .shr-plate__mark{
  mix-blend-mode:multiply;
}
.shr-certs,
.shr-certs .shr-cert{ background-color:#ffffff !important; }
.shr-recognition__bodies{ background:#ffffff !important; }
/*
 * 1.71.1. The certification row kept its white boxes while the awards row lost
 * them, and the reason is stacking contexts. mix-blend-mode blends against the
 * nearest stacking context, not against the page. .shr-cert carries
 * reveal-item, GSAP puts a transform on those, and a transform creates a
 * stacking context, so each mark was blending against its own transparent box
 * and the white ground survived.
 *
 * The awards row worked by accident: its chalk background sits on
 * .shr-recognition__bodies, which IS the transformed element, so the blend had
 * chalk to work against.
 *
 * Giving each cert cell the same chalk it already sits on puts a backdrop
 * inside its own stacking context. Invisible as a panel, because it matches the
 * band, and it is what multiply needs to drop the white out.
 */
.shr-certs .shr-cert{
  min-height:0;
}
.shr-certs .shr-cert p{ display:none; }

/* The awarding bodies row, now a light strip rather than four boxes on navy.
   And "the line showing just about the awards can be removed". */
.shr-recognition__bodies{
  border-top:0;
  margin-top:0;
  padding:36px clamp(20px,4vw,48px);
  background:var(--shr-chalk);
  border-radius:2px;
}
@media (min-width:768px){
  .shr-recognition__bodies{ margin-top:56px;padding:44px clamp(24px,4vw,56px); }
}
.shr-recognition__bodies .shr-plate--word,
.shr-recognition__bodies .shr-plate--word.shr-mono-sm{
  background:none !important;
  border:0 !important;
  min-height:0 !important;
  padding:10px 8px !important;
  color:var(--shr-harbour);
}

/* ---- 36.7 The banner, with the crumb and the rule out --------------------
   The masthead inner used to open on a crumb line and a hairline. With both
   gone the headline needs the space back rather than inheriting a gap where
   they used to be. */

.shr-e-masthead__inner > h1:first-child,
.shr-e-masthead__inner > h2:first-child{ margin-top:0; }

/* =============================================================================
   32. THE STORY BAND'S LABEL COLUMN. 1.68.0
   -----------------------------------------------------------------------------
   33A: the band is centred correctly, and the copy still reads as pushed right,
   because a 379px column was holding one 22px line. The label gets the width a
   label needs and the copy gets the rest.
   ========================================================================== */

@media (min-width:900px){
  .shr-p-story__grid{ grid-template-columns:minmax(0,248px) minmax(0,1fr); }
}
@media (min-width:1280px){
  .shr-p-story__grid{ grid-template-columns:minmax(0,280px) minmax(0,1fr);gap:72px; }
}

/* =============================================================================
   33. THE DRONE VIDEO, FRAMED. 1.68.0
   -----------------------------------------------------------------------------
   33A: "a hard navy rectangle, square corners, no border, no shadow, dropped
   onto a chalk section. It reads as a black box pasted in." It now sits on a
   mat with a hairline and a shadow, the same way a photograph is presented
   everywhere else on the site. Native controls stay: a custom player is an
   accessibility liability and the browser's own is the one a visitor knows.
   ========================================================================== */

.shr-e-section video, .shr-s-section video{
  display:block;width:100%;height:auto;
  background-color:#0b1a28;
  border-radius:0;
  box-shadow:0 26px 58px -30px rgba(8,36,58,.62), 0 0 0 1px rgba(8,36,58,.14);
}
/* Scoped to the editorial engine's own sections on purpose. An unscoped
   figure:has(> video) would reach into any Elementor page that happens to hold
   a video in a figure, and nothing outside these sections asked for a mat. */
.shr-e-section .shr-e-figure:has(> video),
.shr-s-section .shr-e-figure:has(> video),
.shr-e-section figure:has(> video),
.shr-s-section figure:has(> video),
.shr-e-section p:has(> video),
.shr-s-section p:has(> video){
  margin:0 0 1.4em;
  padding:10px;
  background:var(--shr-ivory);
  box-shadow:0 0 0 1px rgba(8,36,58,.08);
}
.shr-bg-harbour .shr-e-figure:has(> video),
.shr-bg-harbour figure:has(> video),
.shr-bg-harbour p:has(> video){
  background:rgba(251,250,247,.06);
  box-shadow:0 0 0 1px rgba(251,250,247,.12);
}

/* =============================================================================
   37. KATHLEEN'S 24 SEPTEMBER LIST, PART 2. BATCH TWO, THE PAGES
   1.72.0
   -----------------------------------------------------------------------------
   Batch one was the chrome that repeats on every page. This is the four things
   she asked for inside the pages themselves: the banner that carries a name and
   nothing else, the Key Considerations folded into her three categories, the
   Questions section redesigned, and the photographs spread through a page
   instead of piled at the foot of it. Plus the project gallery, which she wants
   as one scroll with no categories and no header.
   ========================================================================== */

/* ---- 37.1 The blurb, in the page, in two columns -------------------------
   "Can the project blurbs be in two columns." Her red box is around the empty
   left third of the story band. The label column is out of the markup; this is
   what the words do with the width they have got back.

   Two columns, not two of anything else: the measure stays at a comfortable
   reading length in each column, the rule between them is the only ornament,
   and a list or a spec table inside the copy is never allowed to break across
   the gutter. Below 1024px it is one column, because two columns of 40
   characters is a newspaper, not a reading page. */

.shr-p-story__body{ max-width:none; }
.shr-p-story__lede{
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.35rem,2.1vw,1.75rem);line-height:1.45;
  color:var(--shr-harbour);
  margin:0 0 1.1em;
  max-width:34ch;
}
.shr-p-story__body > p{ max-width:68ch; }

@media (min-width:1024px){
  .shr-p-story__body--two{
    columns:2;column-gap:72px;
    column-rule:1px solid rgba(90,107,120,.2);
  }
  .shr-p-story__body--two > *{
    break-inside:avoid;
    -webkit-column-break-inside:avoid;
  }
  .shr-p-story__body--two > p{ max-width:none; }
  /* The opening line runs across both columns, so the section still has a
     front door rather than starting mid-paragraph on the left. */
  .shr-p-story__body--two > .shr-p-story__lede{
    column-span:all;max-width:46ch;margin-bottom:1.4em;
  }
}

/* ---- 37.2 Key Considerations, her three ----------------------------------
   Three categories across, each carrying the page's own items. The item's own
   title leads its paragraph in Deep Harbour so the reader can still see what
   the author wrote, and the category name is the heading.

   The cards are set to stretch and the body to fill, so three categories
   holding two, three and two items still draw three cards of the same height
   with their rules aligned. No row with a hole in it. */

.shr-s-cards--kc{ align-items:stretch; }
.shr-s-cards--kc .shr-s-card{
  display:flex;flex-direction:column;
}
.shr-s-cards--kc .shr-s-card h3{
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.35rem,2.1vw,1.7rem);line-height:1.25;
  margin:0 0 .55em;
}
.shr-s-cards--kc .shr-s-card__body{ flex:1 1 auto; }
.shr-s-cards--kc .shr-s-card__body p{
  font-size:17px;line-height:1.7;margin:0 0 1.05em;
}
.shr-s-cards--kc .shr-s-card__body p:last-child{ margin-bottom:0; }
/* 1.74.5, from REPORT 37E. THE CARD FLOOR IS WITHDRAWN.

   1.74.4 aligned the three cards by stretching the boxes and drawing a rule
   under each. It made it worse: the shortest card went from a column that
   ended early to a BOUNDED empty box carrying 438px of nothing above its own
   rule, which is the half empty section THE STANDARD names, drawn in ink.

   The copy does not divide into three equal thirds and no amount of moving
   items between her categories makes it. Rebalancing by text weight was
   simulated twice and rejected both times: it puts shotcrete facing under
   Sustainability and erosion control under Planning & Integration, which is
   worse writing to win a pixel.

   So the cards align at the TOP, on their rules, and each one ends under its
   own last line. Three columns of unequal length under three aligned rules is
   an editorial grid, which is what this is. There is no floor to fall short
   of. DO NOT reintroduce one. */
.shr-s-cards--kc{ align-items:start; }
.shr-s-kc__lead{
  font-weight:600;color:var(--shr-harbour);
}
.shr-bg-harbour .shr-s-kc__lead{ color:var(--shr-sky); }

/* ---- 37.3 The Questions section, redesigned ------------------------------
   "The Questions section, I'll leave that to you to redesign", then "same as
   previous" on every page after it.

   It was a single 720px column of thin closed rows. Fourteen of those is a
   metre of grey lines. Two columns from 1024px halves the run, the question
   is set at reading size in the display face, and the whole row is a 60px
   press target rather than a line of text. Nothing opens on its own and
   nothing moves until somebody asks it to. Rule 15. */

.shr-s-faq--two{ border-top:0; }
@media (min-width:1024px){
  .shr-s-faq--two{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:72px;align-items:start;
  }
  /* Each column keeps its own hairline at the top so the two read as one
     set rather than as two lists that happen to sit side by side. */
  .shr-s-faq--two > .shr-s-q:first-child,
  .shr-s-faq--two > .shr-s-q:nth-child(2){ border-top:1px solid rgba(90,107,120,.24); }
  .shr-bg-harbour .shr-s-faq--two > .shr-s-q:first-child,
  .shr-bg-harbour .shr-s-faq--two > .shr-s-q:nth-child(2){ border-top-color:rgba(251,250,247,.2); }
}
@media (max-width:1023px){
  .shr-s-faq--two{ border-top:1px solid rgba(90,107,120,.24); }
  .shr-bg-harbour .shr-s-faq--two{ border-top-color:rgba(251,250,247,.2); }
}

/* The question is a real h3 inside the control now, so it needs its heading
   styling reset to the summary's own type rather than the h3 default. */
.shr-s-q__q{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.125rem,1.7vw,1.35rem);line-height:1.35;
  color:inherit;letter-spacing:0;text-transform:none;
}
.shr-s-q > summary{ padding:22px 0;min-height:60px;align-items:center; }
.shr-s-q__mark{ margin-top:0; }
.shr-s-q__a{ padding-bottom:26px; }
.shr-s-q__a :where(p){ font-size:17px;line-height:1.7; }

/* ---- 37.4 A photograph between the sections ------------------------------
   The surplus photographs, dealt through the page rather than stacked at the
   end. It sits at section width under the copy it follows, with the same top
   rule the engine gives a figure anywhere else. */

.shr-s-band{ margin-top:56px; }
@media (min-width:768px){ .shr-s-band{ margin-top:72px; } }
.shr-s-band .shr-e-figure{ margin:0; }

/* ---- 37.5 The project gallery, one scroll --------------------------------
   "I don't think we need the category grouping. Can it just be one full
   gallery to scroll through", and "remove The Photographs header."

   Six chosen, the room cards and the disclosure are all out of the markup, so
   what is left is the grid, which was drawn for 150px thumbnails inside a
   closed list and is now the gallery itself.

   IT IS LAID OUT ON SIX TRACKS, NOT THREE, and that is the whole trick. A
   frame normally takes two tracks, which is the three-up rhythm; the leading
   frame takes four and two rows; and when the last row would be left short,
   its frames take three tracks each instead of two and close it exactly. Six
   is the smallest number divisible by both two and three, so every one of
   those arrangements lands on a track boundary and no row ever has a hole in
   it, at any number of photographs. THE STANDARD.

   The old six-up highlight rules, the room chips and the disclosure button
   stay in this stylesheet, unused and harmless, so 1.47.0 can be restored in
   one paste if she changes her mind. */

.shr-p-photos .shr-p-all__grid--open{
  margin-top:0;
  gap:16px;
  grid-template-columns:minmax(0,1fr);
}
.shr-p-photos .shr-p-all__grid--open .shr-p-all__item{ aspect-ratio:3/2; }

/* Two up on a tablet, on four tracks. */
@media (min-width:600px) and (max-width:1023px){
  .shr-p-photos .shr-p-all__grid--open{
    grid-template-columns:repeat(4,minmax(0,1fr));gap:18px;
  }
  .shr-p-photos .shr-p-all__grid--open > .shr-p-all__item{ grid-column:span 2; }
  .shr-p-photos .shr-p-all__grid--lead > .shr-p-all__item--lead{
    grid-column:span 4;aspect-ratio:16/9;
  }
  /* One frame left on its own row: it takes the row. */
  .shr-p-photos .shr-p-all__grid--open:not(.shr-p-all__grid--lead) > .shr-p-all__item:last-child:nth-child(odd),
  .shr-p-photos .shr-p-all__grid--lead > .shr-p-all__item:last-child:nth-child(even):not(.shr-p-all__item--lead){
    grid-column:span 4;aspect-ratio:16/9;
  }
}

/* Three up from a laptop, on six tracks. */
@media (min-width:1024px){
  .shr-p-photos .shr-p-all__grid--open{
    grid-template-columns:repeat(6,minmax(0,1fr));gap:22px;
  }
  .shr-p-photos .shr-p-all__grid--open > .shr-p-all__item{ grid-column:span 2; }
  .shr-p-photos .shr-p-all__grid--lead > .shr-p-all__item--lead{
    grid-column:span 4;grid-row:span 2;aspect-ratio:auto;
  }
  /* One frame left over: it takes the whole row, as a letterbox. */
  .shr-p-photos .shr-p-all__grid--open > .shr-p-all__item:last-child:nth-child(3n+1):not(.shr-p-all__item--lead){
    grid-column:span 6;aspect-ratio:21/9;
  }
  /* Two left over: three tracks each, which is exactly half the row. The
     second selector is the one before it, identified by counting from the
     end, so the pair always widens together. */
  .shr-p-photos .shr-p-all__grid--open > .shr-p-all__item:last-child:nth-child(3n+2),
  .shr-p-photos .shr-p-all__grid--open > .shr-p-all__item:nth-last-child(2):nth-child(3n+1):not(.shr-p-all__item--lead){
    grid-column:span 3;aspect-ratio:16/9;
  }
}

.shr-p-photos .shr-p-all__item{
  transition:transform .6s cubic-bezier(.22,.61,.36,1);
}
.shr-p-photos .shr-p-all__item img{
  transition:transform .8s cubic-bezier(.22,.61,.36,1);
}
.shr-p-photos .shr-p-all__item:hover img,
.shr-p-photos .shr-p-all__item:focus-visible img{ transform:scale(1.03); }
.shr-p-photos .shr-p-all__item:focus-visible{
  outline:2px solid var(--shr-blue);outline-offset:3px;
}
@media (prefers-reduced-motion:reduce){
  .shr-p-photos .shr-p-all__item img{ transition:none; }
  .shr-p-photos .shr-p-all__item:hover img,
  .shr-p-photos .shr-p-all__item:focus-visible img{ transform:none; }
}

/* The band keeps its own breathing room now that nothing sits above the grid. */
.shr-p-photos{ padding-top:clamp(56px,7vw,104px); }

/* ---- 37.6 The line above the awarding bodies ----------------------------
   H9. Kathleen put a red arrow on the hairline immediately above the awards
   logos: "can you remove the line showing just above these logos."

   It was a divider between the four named wins and the row of awarding
   bodies. 1.71.0 gave that row a light ground of its own so the marks could
   sit on it without plates, and 1.71.2 made that ground pure white, which
   means the row is now separated from the navy band by an edge of its own and
   the hairline is doing nothing but drawing a line inside a white panel.

   Out it comes, and the panel gains side padding so it reads as a deliberate
   strip of light at the foot of the band rather than a rule with logos on it. */

.shr-recognition__bodies{
  border-top:0 !important;
  padding:34px 28px;
}
@media (min-width:768px){
  .shr-recognition__bodies{ padding:40px 40px; }
}

/* =============================================================================
   38. REPORT 36A. THE FOUR THINGS IT FOUND. 1.73.0
   -----------------------------------------------------------------------------
   36A came back clean on the blast radius, on the banners, on the three
   Key Considerations, on the redesigned questions, on the ungrouped gallery
   and on the closed last row. Four things it did find are fixed here and in
   inc/service-plan.php, inc/content-sections.php and assets/js/viewer.js.

   This section is the fourth: the viewer was giving the photograph about a
   third of the screen it exists to fill.
   ========================================================================== */

/* ---- 38.1 The viewer gives the photograph the screen ---------------------
   Measured in 36A: on a 631px tall window the stage computed to 1150 by 404
   and a 1150 by 862 photograph rendered at 474 by 356. The bar above and the
   filmstrip below were taking 227px of a 631px screen, and because the
   photograph is height limited rather than width limited, every pixel taken
   off its height takes one and a third off its width as well.

   Three changes. The chapter chips are gone from the bar (viewer.js), which
   removes a wrapped row on anything under 1100px. The filmstrip is smaller,
   and on a short screen it is not there at all, because on a laptop lid the
   photograph matters more than a row of 84px thumbnails. And the stage keeps
   less padding when there is less height to give away.

   On that same 631px window the stage now has about 540px instead of 404,
   which is a photograph about 720px wide instead of 474. */

.shr-viewer__foot{ padding:8px 16px 14px;gap:10px; }
@media (min-width:768px){ .shr-viewer__foot{ padding:10px 28px 16px;gap:10px; } }
.shr-viewer__thumb{ width:64px;height:46px; }
.shr-viewer__count{ font-size:.75rem; }

@media (max-height:820px){
  .shr-viewer__thumbs{ display:none; }
  .shr-viewer__bar{ padding-block:10px; }
  .shr-viewer__title{ font-size:1.05rem; }
}
@media (min-width:768px) and (max-height:820px){
  .shr-viewer__stage{ padding:12px 120px; }
}
@media (max-height:620px){
  .shr-viewer__foot{ padding:6px 16px 10px; }
}

/* ---- 38.2 The certifications row, at every width -------------------------
   REPORT 36B: "Below 1200 the row breaks to 4 then 2, leaving two empty slots
   at the right of the bottom row."

   THE STANDARD: no row has a hole in it. The grid was written for seven
   marks, in fixed tracks of two, four and seven. The row holds six, so at
   1200 and above one track sits empty at the right, and between 768 and 1199
   the six break four and two.

   Fixed tracks cannot survive a change in the number of marks, and this row
   has already been five, six and seven this month. It becomes a centred wrap
   instead, the same device this stylesheet already uses for the three-up
   cards and the room chips: three to a row on a tablet and a laptop, all of
   them on one centred row from 1200. Any count reads as one deliberate
   block, and the next time a certification is added or removed nothing has to
   be rewritten. */

@media (min-width:768px){
  .shr-certs__grid{
    display:flex;flex-wrap:wrap;justify-content:center;align-items:stretch;
    gap:28px;
  }
  .shr-certs__grid > *{ flex:0 1 calc(33.333% - 20px);min-width:0; }
}
@media (min-width:1200px){
  .shr-certs__grid{ gap:20px; }
  .shr-certs__grid > *{ flex:0 1 calc(16.666% - 18px);min-width:150px; }
}

/* =============================================================================
   39. THE ABOUT PAGE, ON THE EDITORIAL TEMPLATE. 1.74.0
   -----------------------------------------------------------------------------
   Kathleen's A1 to A10. The page moves off Elementor Canvas and onto the
   engine, so the banner, the section rhythm, the photograph dealing, the logo
   grounds, the closing band and the footer all come from the rules the rest of
   the site already follows, and stay that way the next time one of them
   changes.

   Three things the engine did not have a shape for before this page needed
   them, all of them general rather than About-specific: a row of figures, a
   row of people, and a captioned portrait inside reading copy.
   ========================================================================== */

/* ---- 39.1 A row of figures ----------------------------------------------
   "30+ Years on the North Shore", "87 Industry Awards", "A+ Better Business
   Bureau Rating". In Elementor this was a designed strip; poured into a
   reading column as six loose paragraphs it would have read as debris.

   The numeral carries the band and the label sits under it in mono, which is
   the same relationship the awards count uses on the home page. Rule 15: the
   figures do not count up, they are simply there. */

.shr-s-figures{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-start;
  gap:40px 32px;
}
@media (min-width:768px){ .shr-s-figures{ gap:48px 72px; } }
.shr-s-figure{ flex:0 1 260px;min-width:0;text-align:center; }
.shr-s-figure__n{
  margin:0;font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(3rem,7vw,4.75rem);line-height:1;letter-spacing:-.01em;
  color:var(--shr-ivory);
}
.shr-s-figure__l{
  margin:14px 0 0;font-family:var(--shr-font-mono);
  text-transform:uppercase;letter-spacing:.14em;font-size:.8125rem;line-height:1.5;
  color:rgba(251,250,247,.72);
}
/* On a light band the same row reads in ink rather than ivory. */
.shr-bg-chalk .shr-s-figure__n,
.shr-bg-paper .shr-s-figure__n,
.shr-bg-ivory .shr-s-figure__n{ color:var(--shr-harbour); }
.shr-bg-chalk .shr-s-figure__l,
.shr-bg-paper .shr-s-figure__l,
.shr-bg-ivory .shr-s-figure__l{ color:var(--shr-slate); }

/* ---- 39.2 A row of people -----------------------------------------------
   A5. "Mark, Kilick, Steve on the top row, then Jesse, Rob, Kat, Misha."

   Her order is already the order the page holds them in, so this is the
   layout and nothing else: the first three take a third of the row each and
   everyone after them takes a quarter, which lands seven people as three and
   then four exactly as she drew it. The row is centred, so a team of five or
   eight still reads as a set rather than leaving a hole. */

.shr-s-people{
  display:flex;flex-wrap:wrap;justify-content:center;
  gap:40px 24px;margin-top:40px;
}
@media (min-width:768px){ .shr-s-people{ gap:48px 32px;margin-top:52px; } }
.shr-s-person{ flex:0 1 200px;min-width:0; }
@media (min-width:768px){
  .shr-s-person{ flex:0 1 calc(25% - 24px); }
  /* 1.108.0. The 33.333% basis that used to sit here for the first three is
     GONE. It is what made the top row bigger, and section 90 below explains
     why that was wrong. Left as a flex fallback, every portrait is now the
     same size whether the grid applies or not. */
}
.shr-s-person figure{ margin:0; }
.shr-s-person img{
  display:block;width:100%;height:auto;aspect-ratio:3/4;object-fit:cover;
  background:var(--shr-fill);
}
.shr-s-person figcaption{
  margin-top:16px;font-size:15px;line-height:1.5;color:var(--shr-slate);
}
.shr-s-person figcaption strong{
  display:block;font-family:var(--shr-font-display);font-weight:400;
  font-size:20px;line-height:1.25;color:var(--shr-harbour);margin-bottom:2px;
}
.shr-bg-harbour .shr-s-person figcaption{ color:rgba(251,250,247,.72); }
.shr-bg-harbour .shr-s-person figcaption strong{ color:var(--shr-ivory); }
.shr-s-people__lead{ max-width:68ch; }

/* ---- 39.3 A captioned portrait inside reading copy -----------------------
   A4. Mark's quote, and his name and title under his photograph beneath it.
   One portrait beside a column of words, never stretched, never cropped to a
   shape the file cannot carry. */

.shr-e-prose figure.shr-portrait,
.shr-e-lede figure.shr-portrait{
  margin:32px 0 0;max-width:300px;
}
@media (min-width:768px){
  .shr-e-prose figure.shr-portrait,
  .shr-e-lede figure.shr-portrait{ max-width:340px; }
}
figure.shr-portrait img{ display:block;width:100%;height:auto; }
figure.shr-portrait figcaption{
  margin-top:14px;font-size:15px;line-height:1.5;color:var(--shr-slate);
}
figure.shr-portrait figcaption strong{
  display:block;font-family:var(--shr-font-display);font-weight:400;
  font-size:20px;line-height:1.25;color:var(--shr-harbour);margin-bottom:2px;
}
.shr-bg-harbour figure.shr-portrait figcaption{ color:rgba(251,250,247,.72); }
.shr-bg-harbour figure.shr-portrait figcaption strong{ color:var(--shr-ivory); }

/* Mark's quote opens the page, so it is set as a statement rather than as an
   indented aside. It is the only blockquote on the page. */
.shr-e-prose blockquote,
.shr-e-lede blockquote{
  margin:0 0 8px;padding:0;border:0;max-width:30ch;
}
.shr-e-prose blockquote p,
.shr-e-lede blockquote p{
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.5rem,3.1vw,2.35rem);line-height:1.3;
  color:var(--shr-harbour);
}
.shr-bg-harbour .shr-e-prose blockquote p,
.shr-bg-harbour .shr-e-lede blockquote p{ color:var(--shr-ivory); }
@media (min-width:768px){
  .shr-e-prose blockquote,
  .shr-e-lede blockquote{ max-width:34ch; }
}

/* =============================================================================
   40. REPORT 36D AND 36E. WHAT THE ABOUT REBUILD SURFACED. 1.74.1
   -----------------------------------------------------------------------------
   The move itself landed: the paste read back exact, A2, A4, A6 and A7 all
   found, seven people three and four with every name under its own face, no
   small labels left on any mark, and the logo guard came back clean across six
   pages with zero photographs drawn at mark size.

   Six things it found. Five are here and one is in inc/content-sections.php.
   Three of them are specificity, which is worth naming plainly: a rule written
   as a single class cannot win against a rule written as a class and an
   element, and this stylesheet sets every paragraph inside a section at 20px
   from such a rule. Anything that is a paragraph and wants its own size has to
   say so at that weight or louder.
   ========================================================================== */

/* ---- 40.1 The figures row, at the size it was designed for ---------------
   36E: "The numeral and the label beneath it both compute to 20 pixels. The
   stylesheet asks for the numeral at clamp 3rem to 4.75rem, but the rule for
   a paragraph inside a section carries higher specificity and wins."

   That rule is `.shr-e-section p`. These two are written at the same weight
   now, which is all it takes.

   And the row itself: at a 260px basis three figures need 924px of inner
   measure, so below about 1163px it broke to two and one and left a hole.
   They share the row instead and only stack on a phone, where three abreast
   would be unreadable anyway. THE STANDARD. */

.shr-e-section .shr-s-figure__n{
  font-size:clamp(3rem,7vw,4.75rem);line-height:1;letter-spacing:-.01em;
  margin:0;
}
.shr-e-section .shr-s-figure__l{
  font-family:var(--shr-font-mono);
  text-transform:uppercase;letter-spacing:.14em;
  font-size:.8125rem;line-height:1.5;margin:14px 0 0;
}
.shr-s-figures{ gap:40px 32px; }
@media (min-width:600px){
  .shr-s-figures{ flex-wrap:nowrap;gap:32px; }
  .shr-s-figure{ flex:1 1 0;min-width:0;max-width:340px; }
}
@media (min-width:1024px){ .shr-s-figures{ gap:56px; } }
@media (max-width:599px){
  .shr-s-figure{ flex:1 1 100%; }
  .shr-e-section .shr-s-figure__n{ font-size:clamp(2.75rem,14vw,3.5rem); }
}

/* ---- 40.2 Mark's portrait, beside his words ------------------------------
   36E: "the portrait is not beside the quotation, it sits below it", and it
   rendered 576 wide against a 340px cap that never applied, because
   `.shr-e-section :where(figure)` sets max-width with an important flag and
   nothing softer than that can answer it.

   A4 reads better as a pair in any case: the quotation on the left, the man
   who said it on the right, which is how the rest of this site sets a person
   against their words. Below 900px it stacks, portrait first at a size that
   does not swallow the screen. */

.shr-e-section figure.shr-portrait{
  max-width:340px !important;margin:32px 0 0;
}
.shr-e-section figure.shr-portrait img{ display:block;width:100%;height:auto; }

@media (min-width:900px){
  /* The pair takes the section's width, not the reading measure, or the
     portrait ends up at 173px inside a 640px column. The quotation keeps its
     own measure through its own max-width, set in section 39. */
  .shr-e-prose:has(> blockquote):has(> figure.shr-portrait),
  .shr-e-lede:has(> blockquote):has(> figure.shr-portrait){
    display:grid;
    grid-template-columns:minmax(0,7fr) minmax(0,4fr);
    column-gap:72px;align-items:center;
    max-width:1100px;width:100%;margin-inline:auto;
  }
  .shr-e-prose:has(> blockquote):has(> figure.shr-portrait) > blockquote,
  .shr-e-lede:has(> blockquote):has(> figure.shr-portrait) > blockquote{
    grid-column:1;margin:0;
  }
  .shr-e-prose:has(> blockquote):has(> figure.shr-portrait) > figure.shr-portrait,
  .shr-e-lede:has(> blockquote):has(> figure.shr-portrait) > figure.shr-portrait{
    grid-column:2;grid-row:1 / span 99;margin:0;align-self:center;
  }
  .shr-e-prose:has(> blockquote):has(> figure.shr-portrait) > p,
  .shr-e-lede:has(> blockquote):has(> figure.shr-portrait) > p{ grid-column:1; }
}

/* ---- 40.3 The marks, on a ground that matches the files ------------------
   36E sampled the four corner pixels of all eight: six carry an opaque block
   baked into the artwork. Five are white and one, Energy Star, is the cyan
   that mark is actually issued in.

   The home page solved this in 1.71.2 by matching the ground to the files. The
   same answer works everywhere, so the marks row on any engine page now sits
   on its own white panel rather than on cream. Five of the six rectangles
   disappear by definition, HAVAN and RenoMark are unaffected, and Energy Star
   reads as the blue badge it is issued as, which rule 16 asks for.

   The real fix is transparent source files and it is still worth doing before
   launch. This is the fix that is right today. */

.shr-e-section [data-shr-marks]{
  /* 1.90.2: the section's own ground, painted here so it sits INSIDE the
     blending group GSAP's transform creates on .reveal-item. Section 78. */
  background:var(--shr-ground, var(--shr-paper));
  padding:28px 32px;
  margin-inline:0;
  border-radius:2px;
}
@media (max-width:599px){
  .shr-e-section [data-shr-marks]{ padding:22px 20px;gap:24px 28px; }
}
/* A mark the client has as words rather than a file, so it reads as part of
   the row instead of as stray bold text under it. */
.shr-e-section [data-shr-marks] strong{
  font-family:var(--shr-font-mono);font-weight:500;
  text-transform:uppercase;letter-spacing:.12em;font-size:.8125rem;
  line-height:1.3;color:var(--shr-slate);
}

/* ---- 40.4 A marks row never sits in half a split -------------------------
   36E: "the Memberships row leaves a large empty area below the logos where
   the split column runs short of the sticky photograph beside it."

   Two rows of logos are naturally short and the photograph beside them is
   naturally tall, so the column ran out and left a hole a third of the band
   deep. A section carrying a marks row takes the full width and puts its
   photograph beneath, where it can run at a size worth looking at. */

.shr-e-split:has(.shr-e-split__copy [data-shr-marks]){
  display:block;
}
.shr-e-split:has(.shr-e-split__copy [data-shr-marks]) > .shr-e-split__copy{
  max-width:none;
}
.shr-e-split:has(.shr-e-split__copy [data-shr-marks]) > .shr-e-split__media{
  margin-top:56px;
}

/* ---- 40.5 The closing band, with nothing beside it -----------------------
   36E: "the closing band leaves its whole right half empty."

   1.48.0 shortened the band at Kathleen's request and took the office and
   hours column out of it. The two column grid stayed, so on every page since
   then the band has been a heading and a button in the left half of a room
   built for two. If the grid has one child it is one column. */

.shr-s-cta-band__grid:not(:has(> * + *)){
  grid-template-columns:minmax(0,1fr) !important;
  max-width:62ch;
}

/* ---- 40.6 The project blurb's opening line -------------------------------
   Same specificity trap as 40.1, found while fixing it. 1.72.0 set the
   project story lede in the display face at up to 1.75rem; `.shr-p-story p`
   has been overriding it at 20px ever since, on every project page. */

.shr-p-story .shr-p-story__lede{
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.35rem,2.1vw,1.75rem);line-height:1.45;
  color:var(--shr-harbour);margin:0 0 1.1em;
}

/* =============================================================================
   41. REPORT 36F. THE THREE THINGS IT FOUND. 1.74.2
   -----------------------------------------------------------------------------
   36F passed every fix it was sent to check. The figures read 76px against a
   13px label, the row is full at all eight widths tested, the portrait pairs
   with the quotation from 900 up and stacks below it, seven of the eight marks
   come back clean with only Energy Star's own cyan artwork left, the 2017
   banner is out, and all five project pages carry their blurb correctly with a
   24.8px serif opening line over 20px body copy.

   Three things it found instead. The closing band is fixed in
   inc/content-sections.php; these two are here.
   ========================================================================== */

/* ---- 41.1 A marks section uses the width it is given ---------------------
   36F: the Certifications and Memberships section renders "a single centred
   column 720 pixels wide with a 576 pixel text measure inside it" in a 1345
   pixel band, "noticeably narrower than the sections above and below it."

   720px is the reading measure, which is right for paragraphs and wrong for
   two rows of logos: it is why BC ENERGY STEP CODE was pushed onto a line of
   its own 124 pixels below the marks rather than sitting in the row with
   them. A section holding a marks row takes the band's full width, and the
   prose inside it keeps its own measure. */

.shr-e-section .shr-e-prose:has([data-shr-marks]),
.shr-e-section .shr-e-narrow:has([data-shr-marks]){
  max-width:none;
}
.shr-e-section .shr-e-prose:has([data-shr-marks]) > :where(p, h2, h3, .shr-e-head),
.shr-e-section .shr-e-narrow:has([data-shr-marks]) > :where(p, h2, h3, .shr-e-head){
  max-width:68ch;
}

/* ---- 41.2 The channel between the quotation and the portrait -------------
   36F at 1440: "the gap between the end of the quotation text and the start
   of the portrait is 238 pixels. About 72 of that is the grid gutter; the
   rest is the blockquote stopping short of its own column because of its
   reading measure."

   Inside the pair the blockquote already has a column of its own doing the
   measuring, so its own cap is what was leaving the channel. It fills its
   column, and the gutter comes in to 56. */

@media (min-width:900px){
  .shr-e-prose:has(> blockquote):has(> figure.shr-portrait),
  .shr-e-lede:has(> blockquote):has(> figure.shr-portrait){
    column-gap:56px;
    grid-template-columns:minmax(0,8fr) minmax(0,4fr);
  }
  .shr-e-prose:has(> blockquote):has(> figure.shr-portrait) > blockquote,
  .shr-e-lede:has(> blockquote):has(> figure.shr-portrait) > blockquote{
    max-width:none;
  }
}

/* =============================================================================
   42. REPORT 36G. 1.74.3
   -----------------------------------------------------------------------------
   36G passed all three fixes. The closing band holds a button on all six pages
   with no empty column, every client sentence survived the link lift word for
   word, the marks section now matches the sections either side of it, BC
   ENERGY STEP CODE sits in the row rather than below it, and the channel
   between the quotation and the portrait came down from 238 pixels to 56.

   Four things it found. Two are here, two are in PHP.
   ========================================================================== */

/* ---- 42.1 The pair stops pairing at 900 ---------------------------------
   36G: at 900 the vertical overlap between the quotation and the portrait
   drops to 37.89 pixels and the portrait hangs 309 pixels below the
   quotation, so "it reads less as a pair and more as a portrait slipping
   past the quotation."

   Two things side by side that barely touch are not a pair, they are a hole
   with a picture next to it. The pair now needs 1024, and between 900 and
   1023 they stack, which they already did cleanly below 900. */

@media (min-width:900px) and (max-width:1023px){
  .shr-e-prose:has(> blockquote):has(> figure.shr-portrait),
  .shr-e-lede:has(> blockquote):has(> figure.shr-portrait){
    display:block;max-width:none;
  }
  .shr-e-prose:has(> blockquote):has(> figure.shr-portrait) > figure.shr-portrait,
  .shr-e-lede:has(> blockquote):has(> figure.shr-portrait) > figure.shr-portrait{
    margin-top:32px;
  }
}

/* ---- 42.2 The marks row is not reading copy -----------------------------
   36G: inside the 900 pixel text measure the five membership marks broke
   four and one, "row two holds a single mark running from 144 to 279,
   leaving 733px clear to its right. That row is mostly empty."

   41.1 gave the marks section the band's full width and then capped its
   paragraphs at 68 characters so the prose would still read properly. A
   marks row IS a paragraph, so it was capped with them. Five marks need
   about 930 pixels and had 900. It takes the full width now and the prose
   keeps its measure, which is what 41.1 was trying to do in the first place.
   THE STANDARD: no row has a hole in it. */

.shr-e-section .shr-e-prose:has([data-shr-marks]) > p[data-shr-marks],
.shr-e-section .shr-e-narrow:has([data-shr-marks]) > p[data-shr-marks],
.shr-e-section .shr-e-prose:has([data-shr-marks]) > :where(ul, ol)[data-shr-marks],
.shr-e-section .shr-e-narrow:has([data-shr-marks]) > :where(ul, ol)[data-shr-marks]{
  max-width:none;
}

/* ==========================================================================
   43. REPORT 37D. 1.74.4
   ========================================================================== */

/* 43.1 The photographer's credit under the masthead.

   Set the Caption field on the attachment and it prints here, quiet, under
   the lede, in the same mono the rest of the site uses for a label. It is a
   credit rather than reading copy, so it stays at label size: rule 15 governs
   what a visitor reads and presses, not a line of small print that exists
   because a licence asks for it. */
.shr-e-masthead__credit{
  margin:28px 0 0;
  font-family:var(--shr-font-mono);
  text-transform:uppercase;letter-spacing:.14em;
  font-size:.75rem;line-height:1.6;
  color:var(--shr-slate);
}
.shr-s-masthead--image .shr-e-masthead__credit{ color:rgba(251,250,247,.62); }
@media (min-width:1024px){ .shr-e-masthead__credit{ margin-top:36px; } }

/* ==========================================================================
   44. REPORT 37E. 1.74.5
   ========================================================================== */

/* 44.1 The credit belongs under the headline, not above it.

   The masthead inner is a two column GRID at 1024 and up. The credit was
   auto placed and landed in the first cell, so it rendered as an eyebrow ABOVE
   the headline on desktop and below it at 390: the same markup answering the
   question two different ways. It is placed now. Bottom left, opposite the
   lede, which is bottom right. */
@media (min-width:1024px){
  .shr-s-masthead .shr-e-masthead__credit{
    grid-column:1;grid-row:3;align-self:end;margin:0;padding-bottom:10px;
  }
}

/* 44.2 WITHDRAWN AT 1.74.6. See section 45. */

/* ==========================================================================
   45. REPORT 37F. 1.74.6
   ========================================================================== */

/* 45.1 A long section is not a split.

   1.74.5 gave the reading copy the wide track. It fixed the measure, 346px to
   485px and 30 characters a line to 43. It fixed it by taking the width off
   the photograph: 485x364 down to 346x260, about 46 per cent less picture, on
   a file the client commissioned at 2560px, while five other sections on the
   same page ran theirs at 911. REPORT 37F was right that one track cannot
   widen without the other narrowing, and right that the page then read as a
   text page with a thumbnail beside it rather than a builder showing work.

   So a long section stops being a split. The copy runs at the body measure,
   centred, and the photograph runs the full width of the section beneath it,
   which is the treatment the other five sections already use. Both get their
   best size instead of being traded against each other, and every photograph
   on the page now renders at one width.

   A short section keeps the split with its original column ratio. Sixty words
   beside a large photograph is what a split is good at. */

.shr-e-stack__copy{ max-width:var(--shr-measure-body);margin-inline:auto; }
.shr-e-stack__media{ margin-top:clamp(36px,4.5vw,64px); }
@media (min-width:1024px){
  .shr-e-stack__media{ margin-top:clamp(48px,5vw,80px); }
}

/* ==========================================================================
   46. REPORT 38C. 1.74.9
   ========================================================================== */

/* 46.1 The services index gives the reading copy the wide track.

   REPORT 38C measured the copy column on /services/ at 346px, about 29
   characters a line, setting 7 to 15 line paragraphs at 20px. The type size
   meets rule 15; the measure does not, and on a reader over fifty a 29
   character line is the harder of the two problems. The split handed the
   photograph 7fr and the copy 5fr, the same imbalance REPORT 37E found on the
   editorial pages.

   SCOPED, NOT GLOBAL. .shr-e-split is emitted in exactly two places: this
   index, and a prose section under 80 words on an editorial page. That second
   case is the one the split is good at, a short paragraph beside a large
   photograph, and widening its copy column would leave space inside the column
   instead of beside it, which is how 1.74.5 traded one hole for another. So
   this is on .shr-l-service-row and reaches nothing else.

   An index photograph is a teaser for the page behind it, not the subject, so
   346px is the right size for it here where it was not on a service page. */
@media (min-width:1024px){
  .shr-l-service-row .shr-e-split{ grid-template-columns:minmax(0,7fr) minmax(0,5fr); }
  .shr-l-service-row .shr-e-split--flip{ grid-template-columns:minmax(0,5fr) minmax(0,7fr); }
}

/* 46.2 The smallest thing on the page was the thing to click.

   38C: the Learn More button sets at 12px with 1.68px of letter spacing, on a
   page whose whole job is to let someone choose what they want built, for an
   audience mostly over fifty. Rule 15 governs what a reader reads AND what
   they press. 14px keeps the mono lockup and the letter spacing intact while
   clearing the floor, and the target was already over 44px. */
.shr-l-service-row__more .shr-pill{ font-size:.875rem; }

/* ==========================================================================
   47. REPORT 40A. 1.75.0
   ========================================================================== */

/* 47.1 THE WHITE BOXES. Kathleen asked twice; 40A found why CSS alone could
   not do it.

   Her words: "Awards; I don't like these white boxes around each of the
   organization logos. Could those be removed please? Same for the other logos
   in the section below."

   40A measured every file on a canvas. On the awards row the band is navy and
   ALL THREE logo files are opaque white to their corners: HAVAN_Hz_RGB-2Col
   .jpg, GeorgieAward.jpg and chba.png, which has 0 fully transparent pixels of
   26,000. Taking the card away does not remove a white box, it leaves three
   white rectangles floating on navy, which is worse. And the only genuinely
   transparent mark in the library, HAVAN.png at 90.3 per cent, carries dark
   ink that would all but vanish on that navy.

   THE BAND IS WHAT IS WRONG, NOT THE CARD. Move the band to light and the
   card, the plates and the logos' own baked-in white all become the same
   colour as the paper behind them. No boxes, no new artwork, no logo altered,
   and every mark stays in its own colours. Rule 16.

   It also puts the awards immediately above the certifications band, which is
   already white, so the two read as one credentials region instead of a navy
   strip wedged between them.

   "The section below" needed nothing: 40A found the certifications band is
   already white with no padding, border, radius or shadow on its cells. The
   boxes she sees there are inside the image files. */

.shr-recognition{ background-color:var(--shr-paper);color:var(--shr-harbour); }
.shr-recognition__inner h2{ color:var(--shr-harbour); }
.shr-recognition__lede{ color:var(--shr-slate); }
.shr-recognition__figure p{ color:var(--shr-slate); }
.shr-recognition__count{ color:var(--shr-harbour); }
.shr-recognition__all{ color:var(--shr-harbour);border-bottom-color:rgba(8,36,58,.28); }
.shr-recognition__all:hover{ border-bottom-color:var(--shr-harbour); }
.shr-recognition .shr-award,
.shr-recognition .shr-award *{ color:var(--shr-harbour);border-color:rgba(8,36,58,.18); }
.shr-recognition .shr-award__body{ color:var(--shr-slate); }

/* The card, and every plate inside it, stop existing as surfaces. */
.shr-recognition__bodies{
  background:transparent !important;border:0 !important;
  padding:0 !important;border-radius:0 !important;
}
.shr-recognition__bodies .shr-plate,
.shr-recognition__bodies .shr-plate--word,
.shr-recognition__bodies .shr-plate--word.shr-mono-sm{
  background:transparent !important;border:0 !important;border-radius:0 !important;
}
.shr-recognition__bodies .shr-plate--word,
.shr-recognition__bodies .shr-plate--word.shr-mono-sm{ color:var(--shr-harbour); }

/* ==========================================================================
   48. REPORT 40B. 1.75.1. THE BAND IS WHITE, NOT BEIGE
   ========================================================================== */

/* 1.75.0 moved the awards band to paper and left three white rectangles on
   beige. Worse than the navy it replaced, and Quentin was right to say so.

   THE PROOF WAS IN 40B AND I WALKED PAST IT. The certifications band directly
   below carries the SAME white-backed logo files, and it shows no boxes,
   because that band is rgb(255,255,255) and the white baked into the files is
   the same white. A box only appears when the band and the file disagree.

   The theme's own attempt at this, mix-blend-mode:multiply on the marks, can
   never fire: .reveal-item puts a transform and will-change on the container,
   which opens a stacking context and isolates the blend group before it can
   reach the backdrop. Matching the colour needs no blend at all.

   So the band is white. The plates disappear because there is nothing left to
   see, every mark keeps its own colours untouched, rule 16 holds, and the two
   credentials bands read as one region rather than meeting on a seam. */

.shr-recognition{ background-color:#ffffff; }

/* The hairline above the count was sized for the old dark band and is
   invisible on anything light. */
.shr-recognition__figure{ border-top-color:rgba(8,36,58,.18) !important; }

/* 40B: the band ended on about 95px of empty surface above the seam. With both
   bands white the seam is gone, so the gap closes to a normal section join. */
.shr-recognition{ padding-bottom:88px; }
@media (min-width:768px){ .shr-recognition{ padding-bottom:104px; } }

/* ==========================================================================
   49. 1.75.3. A FULL WIDTH PHOTOGRAPH IS A BAND, NOT A POSTER
   ========================================================================== */

/* Measured on the live page at a 1536 viewport, not inferred: every section
   photograph on /services/retaining-wall-systems/ was drawing 1256 wide, and
   the two portrait sources were drawing 1256 by 1675. That is one photograph
   filling more than two screens, and one of them is a soil nail detail shot.
   The page stood 23,067px tall.

   1.74.6 was right to stop splitting long sections and give the photographs
   the full measure. It set no ceiling, so a 3:4 source took its natural height
   at full width and a technical close-up ended up the biggest thing on the
   page. Quentin, looking at it: "some of the photos are wayy too big."

   A full width photograph on a reading page is a band. The cap makes every one
   of them the same band, about 1.9:1, whatever shape the file is, so the page
   reads as one sequence rather than eight different postures. object-fit is
   already cover, so nothing is squashed and nothing is letterboxed.

   82vh keeps it under the fold on a short laptop; 660px stops it growing into
   a poster on a tall screen. Measured after: 1256 by 649, and the page fell to
   19,465px. */

@media (min-width:1024px){
  .shr-e-stack__media > .shr-e-figure,
  .shr-s-band > .shr-e-figure{ max-height:min(82vh,660px); }
  .shr-e-stack__media > .shr-e-figure img,
  .shr-s-band > .shr-e-figure img{ height:100%;object-fit:cover; }
}

/* ===================================================================
   50. THE BLURB GROUP HEADING. 1.76.0, corrected at 1.76.1

   Kathleen's 25 September blurbs group their bullets under her own
   headings. 1.76.0 drew them as paragraphs and set them with a single
   class, which loses to `.shr-p-story__body p` at (0,1,1): the label
   drew at the body's 18px, not its own 12px. THE SAME SPECIFICITY
   TRAP ALREADY ON RECORD IN THIS FILE, written into it the same day.

   Fixed twice over. The label is an h2 now, so that rule cannot reach
   it at all, and every declaration below is set at (0,2,0), which
   beats both that rule and any bare element rule on h2.
   =================================================================== */
.shr-p-story__body .shr-p-story__label{
  margin:2em 0 0;
  padding:0;
  font-family:var(--shr-font-mono);
  font-size:.75rem;
  font-weight:500;
  text-transform:uppercase;
  letter-spacing:.14em;
  line-height:1.4;
  color:var(--shr-harbour);
  break-after:avoid;
  page-break-after:avoid;
  -webkit-column-break-after:avoid;
}
.shr-p-story__body .shr-p-story__label + .shr-p-story__features{
  margin-top:.7em;
  break-before:avoid;
}
.shr-p-story__body > .shr-p-story__label:first-child{ margin-top:0; }

/* A list of one is not a two column list. Glencanyon's Lifestyle Notes
   carries the single item Kathleen wrote, "Family living", and the second
   track sat empty beside it.

   1.76.1 set grid-template-columns here and did nothing at all, because
   section 2 of the fold pass took this list off grid at line 6510: it is
   display:block with columns:2 above 768px. THE PROPERTY I PATCHED WAS
   NOT THE PROPERTY IN FORCE, which is the same miss as align-self at
   1.74.4. Both are set below, so it holds whichever way the list is
   laid out. */
.shr-p-story__features:has(> li:only-child){
  columns:1;
  grid-template-columns:minmax(0,1fr);
}

/* ===================================================================
   51. A GRID OF ONE IS NOT A GRID OF FOUR. 1.78.0

   REPORT 46B on Balmoral. Her entry is the only one of the twenty with
   a single spec line, and .shr-p-story__specs is set to four equal
   tracks above 1024px at line 6401, which overrides the auto-fit rule
   at 4018. Inside the two column prose layout that is a track of about
   85px, so the value stacked a word or two per line.

   GREPPED FOR THE RULE IN FORCE BEFORE WRITING THIS, because 4018 is
   the obvious declaration and it is not the one that wins.
   =================================================================== */
.shr-p-story__specs:has(> div:only-child){ grid-template-columns:minmax(0,1fr); }
.shr-p-story__specs:has(> div:nth-child(2):last-child){ grid-template-columns:repeat(2,minmax(0,1fr)); }

/* ===================================================================
   52. ROUND 3, THE HOME PAGE AND THE SERVICE INTRO. 1.79.0
   Every value below comes from a measurement in REPORT 48A, not an
   estimate, and every selector was grepped for the rule in force.
   =================================================================== */

/* F1 and F35. The opening run of a service page, in two columns.
   The heading and the lede span both, so the section still has a
   front door rather than starting mid-paragraph on the left. */
.shr-e-prose--two{ max-width:min(1180px,100%); }
@media (min-width:900px){
  .shr-e-prose--two{ columns:2;column-gap:72px;column-rule:1px solid rgba(90,107,120,.2); }
  .shr-e-prose--two > .shr-s-head,
  .shr-e-prose--two > .shr-e-lede{ column-span:all; }
  .shr-e-prose--two > p{ max-width:none;break-inside:avoid; } /* 1.87.2, see section 72 */
  .shr-e-prose--two > h3,
  .shr-e-prose--two > ul,
  .shr-e-prose--two > ol,
  .shr-e-prose--two > blockquote,
  .shr-e-prose--two > figure{ break-inside:avoid; }
  .shr-e-prose--two > h3{ break-after:avoid; }
}

/* D1. "still too small". 48A measured the four words at 36px against
   Mark's quote at 36.81px, one pixel apart, so the pillars and the
   pull quote read at the same weight and neither leads. The winning
   rule was the clamp at line 7631, whose 3.2vw only reaches 36px at
   the viewport this site is reviewed on. The cap was never the
   problem; the slope was. */
/* The dead rule that was here at 1.79.0 is deleted. REPORT 50A proved it
   could never apply: see section 53. */

/* D3. The three phrases, larger, with room to breathe. 48A measured
   them at 29.91px inside a 325px measure, which wrapped one short
   quote across four lines. */
.shr-manifesto__mark blockquote{ font-size:clamp(2rem,2.9vw,2.9rem);line-height:1.22; }
@media (min-width:768px){ .shr-manifesto__mark{ max-width:440px; } }

/* D4. "the text + icons are harder to see now". She is right, and the
   cause is the photograph, not the design: 48A sampled the bitmap
   behind the text at 161.4 of 255 average brightness over 322,385
   pixels. It is a high-key image and the 20 per cent dim layer was
   tuned for a darker one. The dim goes to 38 per cent and the icon
   captions come off 80 per cent opacity, which lifts the captions
   from 4.9 to 1 to comfortably past 7 to 1 without touching the
   photograph she asked about. */
.shr-blueprint__dim{ background:rgba(8,36,58,.38); }
.shr-blueprint .shr-spec__ring{ opacity:1; }
.shr-blueprint .shr-spec p,
.shr-blueprint__inner .shr-spec p{ color:var(--shr-ivory);opacity:1;font-size:.8125rem; }

/* ===================================================================
   53. THE WINNING DECLARATION, NOT THE EXPECTED ONE. 1.80.0

   REPORT 50A walked the cascade for four elements and named the rule
   that actually wins for each. Three of them had been patched before,
   repeatedly, at a specificity that could never take. Every selector
   below is written to beat the measured winner, and the winner is
   named in the comment so the next person does not repeat this.
   =================================================================== */

/* D1. THE FOUR WORDS. Winner was .shr-opening .shr-pillar h2 at line
   6283, inside (min-width:768px), specificity 0,2,1, computing 36px.
   THREE separate rules at lines 7625, 7631 and 8868 tried to change
   this with .shr-pillar h2 at 0,1,1. None of them could ever win, and
   source order is irrelevant when the specificity is lower.

   This one carries the same 0,2,1 and sits later in the file, which is
   what makes it apply. Mark's quote measures 36.81px, so 52px at
   review width finally gives the four words the lead Kathleen has now
   asked for twice. */
@media (min-width:768px){
  .shr-opening .shr-pillar h2{ font-size:clamp(40px,4.5vw,60px);line-height:1.08; }
}

/* G1. THE ABOUT BANNER. Kathleen: "I'd like the Quality, Expertise,
   Craftsmanship, and Results in one line across the banner."

   50A found the h1 boxed at 475.5px by the 7fr 5fr grid on
   .shr-s-masthead .shr-e-masthead__inner at line 2660, while THREE
   rules set the h1's own max-width in ch units, resolving to 1152px.
   All three are dead: the track is less than half the narrowest of
   them. Whoever tuned those ch values was adjusting a ceiling 676px
   above the floor.

   So the h1 takes the whole row instead of one track. At 1150px that
   is 911px of content box, and 40px type sets the four words on one
   line with room to spare. The overflow-wrap is a floor, not a fix:
   50A measured a 677px line painting 201px outside a 476px box
   because overflow was visible and overflow-wrap was normal. Nothing
   on this site paints outside its box again. */
@media (min-width:1024px){
  .shr-s-masthead--long .shr-e-masthead__inner > h1{
    grid-column:1 / -1;
    max-width:none;
    font-size:clamp(30px,3.6vw,46px);
    line-height:1.12;
    text-wrap:balance;
  }
}
.shr-e-masthead__inner > h1{ overflow-wrap:break-word; }

/* THE TEAM PAGE NAMES. Winner was .elementor-kit-4027 h2 at 0,1,1,
   computing 68px, beating the child theme's .shr-e-bio__name at 0,1,0.
   A single class can never beat one class plus an element, whatever
   the load order, so this needs 0,2,2 to win without !important and
   without touching Elementor's global kit, which would move every h2
   on every Elementor page.

   68px made the team names the loudest type on the site after the
   mastheads, larger than the 39px section headings on About. */
li.shr-e-bio h2.shr-e-bio__name{ font-size:clamp(26px,2.4vw,34px);line-height:1.15; }

/* ===================================================================
   54. THE TEAM BIOS AND THE MASTHEAD HEIGHT. 1.81.0
   Both written from REPORT 51A's measured structure, not from a guess.
   =================================================================== */

/* G9. Kathleen: "Can you place our names and titles to the right of the
   image above our bios. I don't like it underneath."

   51A gave the structure: li.shr-e-bio is a 4fr 7fr grid holding two
   children. Everything she wants separated is nested together inside
   div.shr-e-bio__id, which is display:block, so the portrait, the name,
   the role and the link stack. That is the whole cause.

   display:contents on __id promotes its four children to grid items of
   the bio itself, so each can be placed without touching the markup.
   The bios live in an Elementor HTML widget, so avoiding a markup edit
   keeps this in the theme where it can be versioned.

   Three consequences 51A flagged, all handled below: the figure's
   24px bottom margin is wrong once it sits beside the text, the sticky
   position was on __id and display:contents discards it, so it moves
   to the figure, and the portrait keeps its 3/4 ratio in the 302px
   track where it already worked. */
@media (min-width:900px){
  .shr-e-bio__id{ display:contents; }
  .shr-e-bio{ grid-template-rows:auto auto 1fr auto; }
  .shr-e-bio__figure{
    grid-column:1;grid-row:1 / span 4;
    position:sticky;top:120px;margin-bottom:0;align-self:start;
  }
  .shr-e-bio__name{ grid-column:2;grid-row:1;margin-top:0; }
  .shr-e-bio__role{ grid-column:2;grid-row:2; }
  .shr-e-bio__body{ grid-column:2;grid-row:3; }
  .shr-e-bio__link{ grid-column:2;grid-row:4;margin-bottom:0; }
}

/* G5 and the masthead heights. 51A: NO RULE ANYWHERE sets height,
   min-height, max-height or aspect-ratio on .shr-e-masthead. Every
   masthead on the site is whatever its own headline happens to
   measure: About 420px, Retaining Walls 576px, Doran 475px. None of
   the three was chosen.

   That also means putting Kathleen's four words on one line at 1.80.0
   shrank the About masthead by about 690px, which flipped her crew
   photograph from side-cropped to top-and-bottom-cropped. All three
   men became visible by accident. Nobody picked 521px and it moves
   again the next time a headline changes length.

   600px is chosen. It is above the tallest of the three, so no
   masthead shrinks, and the bg layer's inset of -12% inflates it to a
   744px photograph box.

   CORRECTION, 1.81.1. This comment said 98 per cent of her frame
   survives. THAT WAS WRONG. REPORT 52A measured 79.3 per cent. I
   counted pixels in the image box and forgot the window the header
   cuts in it: .shr-e-masthead is overflow:hidden and the bg layer is
   inset -12% top and bottom, so 144px of that 744px box is clipped and
   never renders. 600px of the 756.8px frame is visible. All three men
   are in frame left to right, which was the point, but they are cut at
   mid-calf and the boom tip is trimmed. The number in a comment has to
   be the number on the screen. */
@media (min-width:1024px){
  .shr-e-masthead{ min-height:600px; }
}

/* ===================================================================
   55. THREE FAULTS IN 1.81.0. 1.81.1
   All three measured in REPORT 52A, none of them predicted.
   =================================================================== */

/* 1. THE ROW GAP. .shr-e-bio carried gap:80px, set when the card had a
   single row. display:contents gave it four rows, so that 80px now
   appears three times, and the auto rows are taller than their
   contents because the name, role and link keep their own margins.
   52A measured 102px, 80px and 100px between them, and the card grew
   432px taller to hold the same content.

   And a member with no LinkedIn link leaves an empty fourth row with
   its gap still inserted: 137px of dead space at the foot of every
   such card. Row gap to zero, margins carry the rhythm instead, so an
   absent row costs nothing. */
@media (min-width:900px){
  .shr-e-bio{ row-gap:0; }
  .shr-e-bio__name{ margin:0 0 6px; }
  .shr-e-bio__role{ margin:0 0 28px; }
  .shr-e-bio__link{ margin:24px 0 0; }
  .shr-e-bio__body > p:first-child{ margin-top:0; }
}

/* 2. THE DEAD STICKY. 52A: div.shr-e-bio__id still carries
   position:sticky and top:126px, which does nothing on a
   display:contents element. Harmless but misleading, and this build
   has enough rules that claim to do things they cannot. */
@media (min-width:900px){
  .shr-e-bio__id{ position:static;top:auto; }
}

/* 3. THE HEADLINE IS NOT PLACED, IT IS DROPPED. 52A measured all three
   mastheads starting their h1 at exactly the same y, 230px below the
   header top, because padding-top is a fixed 189px on every one. The
   band is now a fixed 600px, so where a headline lands relative to
   centre is decided purely by how many lines it happens to run:
   About 47px high on one line, Doran 19px high on one line, Retaining
   Walls 31px low on two.

   Setting the band height fixed half the problem. This fixes the
   other half: the inner is centred in the band, so a one line and a
   three line headline both sit in the middle. The background layer is
   position:absolute and out of flow, so flex on the header does not
   reach it. */
@media (min-width:1024px){
  .shr-e-masthead{ display:flex;flex-direction:column;justify-content:center; }
}

/* ===================================================================
   56. THE ABOUT PAGE COLUMN, AND THE PLATE. 1.82.0
   Every element and every winning rule below is from REPORT 53A.
   =================================================================== */

/* THE HEADLINE, HALF THE REMAINING OFFSET. 53A found all four
   mastheads now land on exactly +43px below their band centre, which
   means they are at least consistent, and decomposed it:
     22.5px from padding 189px top against 144px bottom
     20.5px from an empty 41px first row in the inner grid
   This closes the padding half. The empty row is not touched, because
   I do not yet have the winning rule for grid-template-rows on
   .shr-e-masthead__inner, and guessing that is how the last four
   patches failed. */
@media (min-width:1024px){
  .shr-e-masthead{ padding-block:var(--shr-band-lg); }
}

/* G3. Kathleen: "Align the Meet The Family blurb with the title."
   53A: the heading is at x 112, which IS the site's content column.
   The blurb is at 279, pushed there by .shr-s-people__lead capping at
   68ch and .shr-e-prose adding margin-left:auto, which split 191px of
   slack and then added 72px of its own padding. THE HEADING WAS NEVER
   WRONG. The blurb was centring itself inside a column the heading
   sits flush to. */
.shr-s-people__lead{ margin-left:0;margin-right:0; }

/* THE FOURTH LEFT EDGE. 53A: the About page has four of them, 112,
   120, 208 and 279, and 112 is the correct one. Proudly North Shore
   sits at 208 because .shr-e-stack__copy centres itself with
   margin-inline:auto inside a 911px column.

   Copy aligns to the content column. It does not centre itself inside
   it while the heading above it sits flush left. This is site wide on
   purpose: 49A found three service pages running three different
   opening measures, and the same rule is part of that. */
.shr-e-stack__copy{ margin-inline:0; }

/* G7. THE WHITE PLATE, AND WHY REMOVING IT WOULD MAKE IT WORSE.
   Kathleen has asked twice for the white boxes off the affiliation
   logos. 53A loaded all eight files to a canvas and measured corner
   alpha and transparent share rather than trusting the extension:
   SEVEN OF THE EIGHT CARRY THEIR OWN OPAQUE RECTANGLE, and three of
   those are .png. Only HAVAN is properly prepared.

   So the plate is not a design choice, it is a cover for
   un-prepared artwork. Delete it and seven white boxes and one blue
   box sit on a warm cream ground.

   This is the same problem the home page awards band had, and the
   same answer she approved at 1.75.1: make the ground white, so the
   white baked into the files has nothing to show against. The plate
   goes transparent and the section carries the white instead. */
/* SUPERSEDED BY SECTION 78, 1.90.2. The white-out below was the banner
   Kathleen asked about in rounds 2, 3 and 4. Left here as one line to put
   back, and deliberately not deleted. */
.shr-e-section:has([data-shr-marks]) [data-shr-marks]{ padding-inline:0; }

/* ===================================================================
   57. ONE LEFT EDGE, AND THE HAIRLINE ABOVE THE HEADLINE. 1.83.0
   All three from REPORT 54A.
   =================================================================== */

/* THE 20.5px WAS NEVER AN EMPTY ROW. 54A: no rule anywhere sets
   grid-template-rows on .shr-e-masthead__inner. The 41px row is
   .shr-e-masthead__inner::after at line 5398, a 1px hairline with a
   40px top margin, and it has NO grid placement of its own. The h1 is
   pinned to row 2 and the breadcrumb to row 1, so on every page that
   renders no breadcrumb the hairline auto-places into row 1 and draws
   ABOVE the headline instead of below it.

   AND KATHLEEN HAS ASKED FOR EXACTLY THIS LINE TO GO, TWICE. Round 2,
   on the Projects banner: "Remove the home text and the line in the
   banner." On the Services banner: "remove Our Core Services and the
   line within the banner." The breadcrumbs went at 1.71.0 and 1.72.0.
   The rule they were paired with stayed, lost its anchor, and floated
   up over the headline.

   It goes. That closes her request and the last 20.5px of masthead
   offset in the same line. */
.shr-e-masthead__inner::after{ display:none; }

/* ONE LEFT EDGE. 54A measured four on the About page: 112, 119.6, 184
   and 279.5, and found one mechanism behind three of them.

   .shr-e-prose caps at 68ch and then centres itself with
   margin-inline:auto. In a 1055px section that is 167.5px of slack
   split evenly, so the copy lands 167.5px right of the heading that
   sits flush at 112. Built For Generations, An Award-Winning Team and
   the Retaining Walls opening run are all the same shape, on three
   different pages.

   Copy aligns to the content column. The cap stays, because a 68ch
   measure is right; what goes is the block centring itself inside a
   column its own heading is flush to. */
.shr-e-prose{ margin-inline:0; }

/* AND THE LAST 72px. 1.82.0 took the auto margin off the Meet The
   Family blurb and recovered 95.5px of the 167.5px gap. 54A found the
   other 72px: .shr-s-people__lead is nested inside .shr-e-inner, so it
   takes the 72px inline padding a second time. Half a fix is a fix
   that still looks wrong to the client. */
.shr-s-people__lead{ padding-inline:0; }

/* ===================================================================
   58. THE HEADLINE IS BREAKING MID-WORD. 1.83.1, URGENT
   =================================================================== */

/* REPORT 55A: the masthead headline chops mid-word on SIX of the eight
   service pages. "Whole Home Renovatio / n". "Kitchen Renovatio / ns".
   "Recreatio / nal Homes". "Complex Site Developm / ent".

   THIS IS MY REGRESSION. 1.80.0 added overflow-wrap:break-word to
   .shr-e-masthead__inner > h1 as a floor, after 50A found a 677px line
   painting 201px outside a 476px box. Before that the word overflowed,
   which looked wrong. Now it breaks, which looks broken. A floor that
   turns one defect into a worse one is not a floor.

   The cause underneath is unchanged and is the real fault: the h1 is
   pinned to grid-column 1, a 475.5px track, at 96px. "Renovation"
   measures about 496px. It was never going to fit. About escapes only
   because .shr-s-masthead--long releases it to the full row at a
   clamped size; the service pages have no such modifier.

   THE TYPE IS SIZED TO ITS COLUMN RATHER THAN THE COLUMN RELEASED.
   Releasing it would need the lede and the rule replaced in the grid,
   and I do not have the winning rules for either. Sizing cannot
   collide with anything. At 1150px this gives 53px, where the longest
   word on any of the eight pages, "Development", measures about 320px
   in a 475px track. The floor stays, and now it never has to fire. */
@media (min-width:1024px){
  .shr-s-masthead .shr-e-masthead__inner > h1{
    font-size:clamp(2.6rem,7vw,4.75rem);
    line-height:1.06;
  }
}

/* AND THE BANNER LINE AND BREADCRUMB SHE ASKED TO REMOVE IN ROUND 2.
   55A found both still rendering on the Projects index: the crumb
   trail in row 1 and the 56x2 rule under the headline. Her words, on
   that exact banner: "Remove the home text and the line in the
   banner." Round 2, 24 September. It was recorded as done at 1.71.0.
   It was done everywhere except the page she named it on. */
.shr-p-masthead .shr-e-crumbs,
.shr-p-masthead .shr-e-rule,
.shr-j-masthead .shr-e-crumbs,
.shr-j-masthead .shr-e-rule{ display:none; }

/* ==========================================================================
   SECTION 59. 1.83.2. THREE FIXES, TWO OF THEM MINE.
   ========================================================================== */

/* 59.1. THE SCOPE OF THE RULE ABOVE WAS WRONG AND IT COST THE JOURNAL.

   1.83.1 hid the crumb trail and the rule with .shr-s-masthead, and EVERY
   masthead on the site carries that class. Read from the templates rather
   than guessed: exactly three of them put a crumb or a rule inside a
   masthead. archive-work.php is the Projects index, which is the page
   Kathleen named. home.php is the Journal index and single.php is a Journal
   article, and on those two the breadcrumb is real navigation. H1 to H4 are
   still open, so she will be on those pages.

   Every other shr-e-rule in the theme sits outside the masthead, so the
   blast radius was exactly those two pages. archive-work.php is the only
   template that emits crumbs alongside .shr-p-masthead, so the selector
   above now names that class instead. Nothing else about the rule changes,
   including its place at the end of the file. */

/* 59.2. THE LEFT EDGE THAT GROWS WITH THE WINDOW.

   G6 was recorded against "An Award-Winning Team" at 184px. REPORT 58A
   measured every top level section on About and they all compute to 112.
   Her item was already closed. The 184 I recorded does not exist on that
   page: the only thing near it is the 180px marker gutter inside
   .shr-e-step, working as designed.

   The real outlier is Industry Leadership at 120px, and it is mine.
   .shr-e-narrow caps at 1040px and centres itself with auto margins. At
   1150px the surplus is 15.2px so the block shifts 7.6px, which is nothing.
   At 1440px the surplus is 320px, the block shifts 160px, and the heading
   lands near 272px while every other heading on the page stays at 112px.
   That is the width most of this audience opens on.

   The measure is right and the centring is wrong, so only the centring
   goes. Scoped to a direct child of a section so it cannot reach the crumb
   blocks in archive-work.php, taxonomy-project.php or taxonomy-service.php.
   Specificity 0,2,0 against the original 0,1,0, so it wins outright and
   does not depend on file order. */
.shr-e-section > .shr-e-narrow{ margin-left:0;margin-right:auto; }

/* 59.3. WITHDRAWN AT 1.83.4. The stack two column treatment is gone and the
   reasoning is in inc/content-sections.php where the class was set. Short
   version: it bought 187px of height and cost 37 characters of line length,
   72 down to 35, on an audience over fifty. The PHP no longer emits
   shr-e-stack__copy--two, so these declarations had nothing left to style. */

/* ==========================================================================
   SECTION 60. 1.83.8. THE TEXT ONLY SECTIONS AND THEIR DEAD SPACE.
   ========================================================================== */

/* Quentin, 28 September, on About: "theres a few open spaces next to texts".
   Measured at his own 1521px window, and he is right by a wide margin:

     Built Like It's Our Own   720px of copy,  761px of empty space beside it
     Industry Leadership      1040px of copy,  441px of empty space beside it
     Principles That Guide    1400px of copy,   60px gap, correct
     An Award-Winning Team    1400px of copy,   60px gap, correct

   More than half of one section is nothing. The neighbours either side use
   the full 1400px inner, so the eye reads it as a section that failed to
   load rather than as a measure.

   WHY NOT JUST WIDEN IT. 1400px at 20px type is about 120 characters a line,
   which is twice the comfortable limit for an audience over fifty.

   WHY NOT CENTRE IT. 1.71.0 set margin-inline:0 across the site on purpose,
   to fix her "this section is now far left and not in line with the rest of
   the page". Centring one block would reopen that.

   SO: TWO COLUMNS, BUT ONLY WHERE THEY ARE ACTUALLY READABLE. The earlier
   two column attempt failed at 1150 because the inner is 911px there, giving
   419px columns and 35 characters. That release was withdrawn and this does
   not repeat it. The gate here is 1400px, where the inner is at least
   1176px, the columns are 548px and up, and the line runs 47 to 57
   characters. Inside 45 to 75 at every width where this rule is live.

   Below 1400px nothing changes at all. */
@media (min-width:1400px){
  .shr-e-section > .shr-e-prose:not(.shr-e-prose--two),
  .shr-e-section > .shr-e-narrow:has(> .shr-s-statement){
    max-width:min(1400px,100%);
  }
  .shr-e-section > .shr-e-prose:not(.shr-e-prose--two) > p{
    max-width:none;
    /* 1.124.0. A PARAGRAPH IS NEVER CUT ACROSS THIS GUTTER EITHER.

       Quentin, 1 October, on About: "make the second paragraph on the right
       side so the sentence isnt cut out." MEASURED on the live page at 1536:
       Built Like It's Our Own set two columns and broke its second paragraph
       mid-sentence, the reader finishing "...a commitment to quality" on the
       left and picking up "craftsmanship, thoughtful design..." at the top of
       the right.

       The fault is an omission, not a new bug. 1.87.2 wrote this exact
       protection for .shr-e-lede--two after he reported the same thing,
       "it doesnt look good when the sentences are cut in half into the right
       side", and .shr-e-prose--two has carried it since 1.79.0. This rule
       added two columns at 1.83.x and never copied it, so it was the one
       columnised run on the site where break-inside stayed auto.

       With avoid, the browser must find a column height that holds each
       paragraph whole, so the taller second paragraph takes the right column
       on its own and the first takes the left. VERIFIED on the rendered page
       before this was written: p1 at left 132, p2 at left 800, both starting
       at the same top. */
    break-inside:avoid;
  }
  .shr-e-section > .shr-e-prose:not(.shr-e-prose--two) > :is(h3,h4,ul,ol,figure,blockquote){
    break-inside:avoid;
  }
  .shr-e-section > .shr-e-prose:not(.shr-e-prose--two) > :is(h3,h4){
    break-after:avoid;
  }
  .shr-e-section > .shr-e-prose:not(.shr-e-prose--two){
    columns:2;
    column-gap:80px;
  }
  .shr-e-section > .shr-e-prose:not(.shr-e-prose--two) > .shr-s-head{
    column-span:all;
  }
}

/* ==========================================================================
   SECTION 61. 1.83.9. THREE OF HER OWN ITEMS, EACH MEASURED FIRST.
   ========================================================================== */

/* 61.1. D3. "The 'We live/build/proven here' can be made larger."

   The caption under it came off at 1.79.0. The lines themselves never moved.
   Measured on the live hero at a 1536px window: three lines at 112px, the
   longest being "We're Proven Here." at 973px inside a 1521px field. The
   usable width after the inner padding is about 1377px, so the headroom is
   1.41x before it wraps.

   132px puts the longest line at about 1147px. That is a visible increase of
   18 per cent and it still leaves 230px of slack, so no line can wrap at any
   width where this rule is live. Below 1024px nothing changes. */
@media (min-width:1024px){
  .shr-hero__lineinner{ font-size:clamp(112px,8.6vw,132px); }
}

/* 61.2. D4. "the text + icons are harder to see now."

   She is right and the numbers say why. The blueprint band is a photograph
   with a scrim over it, and every label on top is Ivory. The scrim measured
   rgba(8,36,58,0.38), and the four small labels, ENGINEERED FOUNDATIONS and
   its siblings, measured 12px with 1.68px of letter spacing.

   12px of widely tracked capitals in Ivory over a bright photograph is the
   hardest thing on this site to read, and Rule 15 puts reading text at 16px
   for this audience. Two changes, both additive.

   The scrim goes from 0.38 to 0.52. The photograph still reads clearly, and
   1.57.0 changed that frame for a brighter one, which is what made the old
   scrim insufficient.

   The labels go from 12px to 15px. The winning declaration was named by the
   browser rather than grepped: a 0,1,0 list rule setting 12px. This is
   scoped to the blueprint at 0,2,0 so it wins outright and moves nothing
   else that uses .shr-mono-sm anywhere on the site. */
.shr-blueprint__dim{ background-color:rgba(8,36,58,0.52); }
/* SUPERSEDED at 1.83.11: see section 63.1. This rule carried no !important
   and lost to four that did. Left as a record, with its declarations removed. */

/* 61.3. E1. "Can we make the cover images per project larger, please?"

   Measured on the live Projects index at a 1536px window: the grid box is
   1256px with 72px of padding each side, so 1112px of content, carrying
   three cards of 336px with 52px gaps. Cover frames draw 336 by 252.

   Two columns would give 530px cards, but that needs 1060 device pixels and
   the fifteen legacy covers top out at 900px on the long edge, so two
   columns cannot ship until those files are replaced. That is recorded as a
   client photography ask, not a grid problem.

   What can ship is the space the grid is giving away. Padding 72 to 40 and
   gap 52 to 36 takes the content to 1176px and the cards to 368 by 276.
   That is 20 per cent more cover area with no change of crop and no new
   files. Gated at 1200px so narrow screens keep their breathing room. */
@media (min-width:1200px){
  .shr-p-grid{ padding-left:40px;padding-right:40px;gap:36px; }
}

/* ==========================================================================
   SECTION 62. 1.83.10. ONE CORRECTION AND ONE ROUTE.
   ========================================================================== */

/* 62.1. THE BLUEPRINT LABEL FIX FROM 1.83.9 DID NOT WIN, AND HERE IS WHY.

   1.83.9 set .shr-blueprint__inner .shr-mono-sm to 15px and the labels stayed
   at 12px. I verified it on the live page before reporting it done, which is
   the only reason this is a correction rather than a false tick.

   The browser named the winner and it is not the one that looks like it:

     .shr-mono-sm:not(.shr-plate--word):not(.shr-cert p) { font-size:12px }

   That scores 0,3,1, because EACH :not() contributes the specificity of its
   own argument. .shr-plate--word adds 0,1,0 and .shr-cert p adds 0,1,1, on
   top of the 0,1,0 of .shr-mono-sm. My rule was 0,2,0 and never stood a
   chance. This is the fifth time on this build that a selector I expected to
   win lost to one I had not read.

   0,4,1 here, so it wins outright rather than on document order, and it is
   still scoped to the blueprint band alone. */
/* SUPERSEDED at 1.83.11: see section 63.1. Specificity was never the problem. */

/* 62.2. I1. THE FOOTER TAKES A FIFTH COLUMN.

   The ten area pages go in the footer, and a fifth column in a four column
   grid would leave a row with a hole in it, which the first line of the
   standard forbids. Five across at the same breakpoint the four used. The
   items are short labels, so the narrower track costs nothing. */
@media (min-width:1024px){
  .shr-footer__cols{ grid-template-columns:repeat(5,1fr); }
}

/* ==========================================================================
   SECTION 63. 1.83.11. THE OPENING SECTION, AND THREE FAULTS I COULD NOT SEE.
   ========================================================================== */

/* 63.1. D4. THE BLUEPRINT LABEL, AND THE PROBE THAT WAS LYING TO ME.

   1.83.9 set this to 15px at (0,2,0) and it stayed 12px. 1.83.10 set it at
   (0,4,1) and it stayed 12px. Both releases carried a note blaming
   specificity. Both notes were wrong.

   The diagnostic I had been running walked every stylesheet like this:

     if (rule.cssRules) { recurse(rule.cssRules); continue; }

   Chrome supports CSS nesting, so EVERY CSSStyleRule now exposes a cssRules
   property: an empty CSSRuleList, which is an object, which is truthy. So
   the walk recursed into nothing and skipped the selector test on every
   style rule on the page. It reported zero matching rules, zero !important
   declarations and zero cascade layers on a page carrying 6,999 rules, and
   I read those zeroes as findings instead of as an impossible result.

   Rewritten to test selectorText first, the browser named the real winners.
   FOUR declarations set this element, and all four carry !important:

     .shr-mono-sm, .shr-eyebrow, ...            12px   !important  (0,1,0)
     .shr-mono-sm, .shr-eyebrow, .shr-e-eyebrow 12.5px !important  (0,1,0) @768
     .shr-mono-sm:not(.shr-plate--word):not(..) 12px   !important  (0,3,1)
     .shr-e-eyebrow, .shr-eyebrow, .shr-mono-sm 12px   !important  (0,1,0)

   An important declaration beats every normal one regardless of specificity,
   so (0,4,1) was never in the contest. The third is the winner among the
   four, on specificity, and it is the one the browser reported.

   This rule is (0,4,1) AND important, so it takes it. Scoped to the
   blueprint band, so nothing else that uses .shr-mono-sm moves. */
.shr-blueprint .shr-blueprint__inner .shr-spec p.shr-mono-sm{
  font-size:15px !important;
  letter-spacing:1.4px !important;
}

/* 63.2. F1, F2, F5, F9, F14, F16, F18, F20, F23. THE OPENING SECTION.

   Kathleen, round 3, on every service page: "I'm disliking the intro blurb
   format as one singular column. Can we change this to be either a more
   stretched format across the page, or two columns? Whatever design you
   think is best." And, twice more: "The image that was next to the intro
   blurb is now gone. I was wanting to add more, not eliminate them."

   MEASURED, 29 September, at a 1536px window, on all eight service pages.
   The opening section is .shr-e-stack on every one of them, and every one
   measures the same shape:

     content column   132 to 1388     1,256px
     copy             132, 720 wide   844 to 1,457 tall
     photograph       132, 1,256 wide 570 tall, BENEATH the copy

   So 536px of the content column is empty down the entire height of the
   copy, and the photograph is parked under it. That is the singular column
   she is describing, and the missing image beside it, in one shape.

   1.83.2 answered this by setting the copy in two columns and REPORT 59A
   measured the result: the height barely moved and the line fell from 72
   characters to 35. Withdrawn at 1.83.4. The answer was never the column
   count. It is that the 536px belongs to the photograph.

   This is the grid the rest of the page is already using, so the opening
   section now reads as part of the page rather than as a preface to it:
   copy on the 7fr track at 667px, photograph on the 5fr track at 477px,
   112px between them. 667px at 20px is about 57 characters, inside the
   45 to 75 range, and it holds the 132px left edge that section 53A made
   site-wide law.

   The figure is sticky inside a stretched column, exactly as the splits
   have been since 1.74.4. Kitchen and Bathroom carry 257 words and 1,457px
   of copy; without this the photograph would stop after 357px and leave
   1,100px of empty column, which is the void REPORT 37D found and named. */
@media (min-width:1024px){
  .shr-e-section .shr-e-stack{
    display:grid;
    grid-template-columns:minmax(0,7fr) minmax(0,5fr);
    gap:80px;
    align-items:stretch;
  }
  .shr-e-section .shr-e-stack__copy{ max-width:none;margin-inline:0; }
  .shr-e-section .shr-e-stack__media{ margin-top:8px; }
  .shr-e-section .shr-e-stack__media > .shr-e-figure{
    max-height:none;
    position:sticky;
    top:126px;
  }
}
@media (min-width:1280px){
  .shr-e-section .shr-e-stack{ gap:112px; }
}

/* 63.3. G4. THE PHOTOGRAPHS ALTERNATE, AND THE COPY STOPS TAKING THE
   NARROW TRACK.

   Kathleen: "a lot of images are appearing underneath blurbs. Let's change
   up the design and have some next to the blurbs on the right and left
   sides so there are visuals along with the text."

   MEASURED on every service page. Section 2 and section 3 both put the copy
   at x=132 and the photograph on the right. The photograph never moves to
   the left. What the --flip class was doing was swapping the TRACK WIDTHS,
   not the order:

     section 2, no flip   copy 477 wide   photograph 667
     section 3, flip      copy 667 wide   photograph 477

   So half the sections on every service page were setting 20px type in a
   477px column, which is about 41 characters. Rule 15's floor is 45, and
   this audience is over fifty. The alternation Kathleen asked for was never
   happening, and the cost of the thing that was happening instead was the
   reading.

   1.74.9 already fixed exactly this on the services index, at
   .shr-l-service-row, after REPORT 38C measured a 346px copy column there.
   The same fault was sitting in the base rule the whole time and nobody
   looked. It is promoted to the base here, so the reading copy holds the
   wide track everywhere and --flip does what its name says: it moves the
   photograph to the other side. */
@media (min-width:1024px){
  .shr-e-split{ grid-template-columns:minmax(0,7fr) minmax(0,5fr); }
  .shr-e-split--flip{ grid-template-columns:minmax(0,5fr) minmax(0,7fr); }
  .shr-e-split--flip > .shr-e-split__copy{ grid-column:2;grid-row:1; }
  .shr-e-split--flip > .shr-e-split__media{ grid-column:1;grid-row:1; }
  .shr-e-split--even{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .shr-e-split--even > .shr-e-split__copy,
  .shr-e-split--even > .shr-e-split__media{ grid-column:auto;grid-row:auto; }
}

/* ==========================================================================
   SECTION 64. 1.83.12. FOUR SECTIONS THAT WERE NOT DOING THEIR JOB.
   ========================================================================== */

/* 64.1. F7. THE QUESTIONS THAT NOW EXIST.

   The accordion is the one 1.72.0 built and Kathleen has already approved at
   /questions/. Inside a 667px reading column it stays one column, and the
   question drops from the section scale to the reading scale so a five word
   question and a fifteen word question both set on one or two lines. */
.shr-s-faq--inline{ margin-top:36px; }
.shr-s-faq--inline .shr-s-q__q{
  font-size:19px;
  line-height:1.4;
}
@media (min-width:1024px){
  .shr-s-faq--inline .shr-s-q__q{ font-size:20px; }
}
.shr-s-faq--inline .shr-s-q > summary{ padding-top:20px;padding-bottom:20px; }
.shr-s-faq--inline .shr-s-q__a{ padding-bottom:24px;max-width:none; }

/* 64.2. F8. THE THREE CARD ROW WHERE THE VIDEO WAS.

   Her Option 1, drawn by the same .shr-p-grid the project pages use, at full
   section width rather than inside the reading column, so the covers are the
   size they are everywhere else on the site. */
.shr-p-more__row{ margin-top:clamp(48px,5vw,80px); }

/* 64.3. D2. THE OTHER FOUR SERVICES.

   Three of seven services named in 2,188px was the lacklustre. The four that
   were missing go beneath the bands as a row of plain tiles: a rule, a name,
   the client's own sentence, and the way in. No photographs, because three
   full bleed photographs above them are already carrying the section and
   four more would make it a catalogue. */
/* 74.1 REMOVED at 1.88.0: .shr-build__rest, __grid, __tile.
   That was the row of four services at the foot of What We Build, added when
   Kathleen asked in round 3 for the section to be "more substantial". In
   round 4 she asked for the list to move up under the header and be drawn as
   icons with a blurb, which section 74 above now does for all six services.
   Keeping both would have listed the same services twice in one section, so
   the markup went and these rules went with it. Nothing else on the site
   used them; checked across every template before deleting.               */


/* ==========================================================================
   SECTION 65. 1.83.13. THE ABOUT PAGE, MEASURED SECTION BY SECTION.
   ========================================================================== */

/* 65.1. THE LEFT EDGE, AGAIN, AND THIS TIME THE CAUSE.

   MEASURED 29 September at 1536 on /about-us/, every section, heading and
   first paragraph: SEVEN sections start their type at 132px and THREE start
   at 112px. Every heading on every service page starts at 132. So About has
   a 20px step in it that no other page has.

   53A chased this before and set .shr-e-prose to margin-inline:0, reasoning
   that copy should align to the content column rather than centre inside it.
   The reasoning was right and the rule was wrong: margin-inline:0 aligns the
   box to the SECTION PADDING at 40px, not to the content column, which is
   the 1400px box .shr-e-inner centres at 60px. 40 plus the 72px gutter is
   112. 60 plus the same gutter is 132. That is the whole of it, and it has
   been on the page since 53A.

   The box keeps its own width and its own left alignment. It is the column
   it sits in that moves. Below 1400px of available width the calculation
   resolves to zero and nothing changes. */
@media (min-width:1024px){
  .shr-e-section > .shr-e-prose,
  .shr-e-section > .shr-e-narrow{
    margin-left:calc((100% - min(1400px, 100%)) / 2);
    margin-right:auto;
  }
}

/* 65.1b. AND THE SAME 72px TWICE.

   "An Award-Winning Team": heading at 132, its own first paragraph at 204.
   A 72px indent under its own heading, on a section 1,198px tall.

   .shr-e-prose is nested inside .shr-e-inner there, and both carry the 72px
   gutter, so the inner box pays it twice. 54A found this exact fault on
   .shr-s-people__lead and fixed that one element by hand. It is the rule
   that is wrong, not the element: a gutter belongs to the outermost box on
   a section, never to a box already inside one. */
.shr-e-inner .shr-e-prose,
.shr-e-inner .shr-e-narrow{ padding-left:0;padding-right:0; }

/* 65.1c. THE TWO COLUMN RUN WAS SETTING 41 CHARACTERS.

   "Proudly North Shore" runs .shr-e-prose--two capped at 1180px. Inside the
   72px gutters that is 1,036px of content, less the 72px column gap, giving
   two columns of 482px. At 20px that is about 41 characters a line. Rule 15
   floors the line at 45 and this audience is over fifty. It is the same
   fault as the service page splits, in a different component.

   On the 1400px column the same block gives two columns of 592px, about 51
   characters, and it lines up with every other section at 132. */
@media (min-width:1024px){
  .shr-e-section > .shr-e-prose--two{ max-width:min(1400px,100%); }
}

/* 65.2. A PORTRAIT PHOTOGRAPH SHOWN AS A LETTERBOX STRIP.

   MEASURED on /about-us/, directly beneath Meet the Family: a figure of
   1256 by 570 holding an image of 1200 by 1600. The figure clips with
   overflow:hidden, so SIXTY-FOUR PER CENT OF THAT PHOTOGRAPH IS NOT ON THE
   PAGE, and what is shown is the top third of a portrait. Kathleen: "The
   image under is cropped oddly."

   The band treatment was written for wide photographs and caps them at
   about 1.9:1 so a page reads as one sequence. A portrait handed the same
   cap does not crop to a band, it is guillotined. It keeps its shape and
   takes a centred column instead, at the same 660px ceiling the wide bands
   use, so it is the same visual weight without losing two thirds of itself. */
@media (min-width:1024px){
  .shr-s-band > .shr-e-figure.shr-e-3x4,
  .shr-e-stack__media > .shr-e-figure.shr-e-3x4{
    width:auto;
    max-width:min(495px,100%);
    max-height:min(82vh,660px);
    margin-left:auto;
    margin-right:auto;
  }
  .shr-s-band > .shr-e-figure.shr-e-3x4 img,
  .shr-e-stack__media > .shr-e-figure.shr-e-3x4 img{
    width:auto;
    height:min(82vh,660px);
    object-fit:cover;
  }
}

/* 65.3. THE FRAME THE FILE ACTUALLY IS.

   The blanket 4:3 that section 7 of the phone rules applied to every split
   photograph at desktop is withdrawn above. shr_sections_ratio() chooses a
   frame from the file's own shape and that rule cancelled it silently on
   every service page, every location page and About.

   Measured cost on one image: 2015 by 1133 drawn at 477 by 357. Twenty-five
   per cent of the frame gone. With 1.83.13's 16:9 bucket the same file draws
   477 by 268 and nothing is cut. */
.shr-e-natural img{ object-fit:contain;height:auto; }

/* ==========================================================================
   SECTION 66. 1.83.14. THE BAND CAP THAT NEVER CAPPED ANYTHING.
   ========================================================================== */

/* MEASURED 29 September at 1536, counting every figure on four pages against
   the image inside it:

     /custom-home-builder/         3 of 6 figures clipped, worst 372px
     /services/retaining-wall-systems/  5 of 8 clipped, worst 372px
     /services/kitchen-renovations/     3 of 6 clipped, worst 267px
     /about-us/                         1 band clipped 267px

   A 1256 by 570 figure holding a 1256 by 942 image. THE BOTTOM 39 PER CENT
   OF THAT PHOTOGRAPH IS NOT ON THE PAGE, and because the image is simply
   top aligned inside overflow:hidden, the part that goes is always the
   bottom. Feet, foundations, the base of a wall, the floor of a room.

   Section 49 wrote the cap and believed it worked, and its own note records
   a measurement of "1256 by 649" as proof. Here is why it does not:

     .shr-s-band > .shr-e-figure     { max-height:min(82vh,660px) }
     .shr-s-band > .shr-e-figure img { height:100%; object-fit:cover }

   A percentage height resolves against the parent's height. max-height is
   not a height: the figure's height is still auto, so height:100% on the
   image computes to auto, aspect-ratio takes over, and the image draws at
   its full frame height and hangs out of the bottom of the box. object-fit
   never runs, because the image was never constrained. The cap was clipping,
   not fitting, for as long as it has existed.

   The figure takes a definite height, so the image's height:100% has
   something to resolve against and object-fit:cover finally does its job.
   The band is the same height it is today. The difference is that the crop
   is now taken from both edges around 45 per cent, where a building sits,
   instead of guillotining the bottom.

   Portraits and banners are excluded: 65.2 gives a portrait its own centred
   column, and .shr-e-natural is contained on purpose. */
@media (min-width:1024px){
  .shr-s-band > .shr-e-figure:not(.shr-e-3x4):not(.shr-e-natural){
    height:min(82vh,660px);
    max-height:none;
  }
  .shr-s-band > .shr-e-figure:not(.shr-e-3x4):not(.shr-e-natural) > img{
    width:100%;
    height:100%;
    object-fit:cover;
    object-position:50% 45%;
  }
}

/* ==========================================================================
   SECTION 67. 1.83.18. THE PULL-QUOTE LEARNS TO CARRY A PHOTOGRAPH.
   ========================================================================== */

/* G2, on the third attempt, and this one moves nothing else.

   Two releases tried to take the pull-quote promotion away from "Industry
   Leadership" so the photograph dealer would reach it. 1.83.15 handed the
   problem to the other section in her sentence. 1.83.16 let the grouping rule
   sweep three sections into one, because the promotion was the only thing
   holding them apart. The promotion was load bearing twice over.

   So it stays. The plan is untouched, the grouping rule sees exactly what it
   saw before, and the statement simply renders in the left track of the same
   grid every other section on the page uses, with the photograph on the right.

   The statement's own type is capped at 24ch, which at its largest is about
   600px, so the 667px track costs it nothing. The photograph is on the right
   because Built For Generations, directly above, carries its own on the left. */
/* 1.83.19. AND THE MEASURE, WHICH I BROKE MYSELF IN 1.83.18.

   The statement's own rule is `.shr-s-statement :where(p)` at (0,1,0), and
   `:where()` contributes nothing, so it loses to `.shr-e-section p` at (0,1,1)
   and this paragraph sets at the page's body size of 20px, not the display
   clamp. That is correct for this block, which is a full paragraph rather than
   a one line pull-quote, and it is how the section has always read.

   What was not correct was the 22ch cap I added on top of it. At 20px that is
   264px, about 22 characters a line, in a 667px track. Rule 15's floor is 45.
   I spent tonight fixing 41 character columns and then shipped a 22.

   The cap comes off. The paragraph takes the track, about 57 characters. */
.shr-s-statement-pair .shr-s-statement{ margin-top:8px; }
.shr-s-statement-pair .shr-s-statement :where(p){ max-width:none; }
@media (min-width:1024px){
  .shr-e-section .shr-s-statement-pair{ align-items:start; }
}

/* ==========================================================================
   SECTION 68. 1.83.21. SHORTCUT NAVIGATION ON A LONG PAGE.
   ========================================================================== */

/* Quentin, 29 September: "We should add shortcut navigation on the about us
   top nav bar as the page is pretty long as well."

   MEASURED: /about-us/ runs 16,291px over twelve sections. A reader who wants
   the certifications has eleven screens to scroll through to find them.

   The bar sits below the masthead and becomes sticky the moment the masthead
   leaves, directly under the fixed 109px header, so it is reachable from any
   point on the page without being in the way at the top of it.

   The links are set at 16px, not at the 12px the mono labels use. Rule 15,
   from REPORT 37D: anything a reader presses reaches 16px, and these are the
   most pressed things on the page. Each one clears 44px of tap height. */

.shr-pagenav{
  position:relative;
  z-index:100;
  background-color:var(--shr-chalk);
  border-top:1px solid rgba(90,107,120,.18);
  border-bottom:1px solid rgba(90,107,120,.18);
}
.shr-pagenav__inner{
  width:100%;max-width:1400px;margin-inline:auto;
  padding-inline:20px;
}
@media (min-width:768px){ .shr-pagenav__inner{ padding-inline:56px; } }
@media (min-width:1024px){ .shr-pagenav__inner{ padding-inline:72px; } }

.shr-pagenav__list{
  list-style:none;margin:0;padding:0;
  display:flex;align-items:center;
  gap:8px 28px;
  overflow-x:auto;
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
}
.shr-pagenav__list::-webkit-scrollbar{ display:none; }
@media (min-width:1200px){
  .shr-pagenav__list{ gap:8px 34px;flex-wrap:wrap;overflow-x:visible; }
}
.shr-pagenav__item{ margin:0;flex:0 0 auto; }
.shr-pagenav__item > a{
  display:flex;align-items:center;
  min-height:52px;
  white-space:nowrap;
  font-family:var(--shr-font-mono);
  font-size:16px;
  letter-spacing:.06em;
  text-transform:uppercase;
  text-decoration:none;
  color:var(--shr-slate);
  border-bottom:2px solid transparent;
  transition:color .2s ease,border-color .2s ease;
}
.shr-pagenav__item > a:hover{ color:var(--shr-harbour); }
.shr-pagenav__item > a:focus-visible{ outline:2px solid var(--shr-blue);outline-offset:3px; }
.shr-pagenav__item.is-current > a{
  color:var(--shr-harbour);
  border-bottom-color:var(--shr-blue);
}
/* The one entry that leaves the page says so. */
.shr-pagenav__item--out{ margin-left:auto; }
.shr-pagenav__item--out > a{ color:var(--shr-blue); }
.shr-pagenav__item--out > a:hover{ color:var(--shr-harbour); }
@media (max-width:1199px){ .shr-pagenav__item--out{ margin-left:0; } }

/* Sticky from the width the fixed header is a full bar. The admin bar shifts
   the viewport for a signed-in editor only, so it gets its own offset. */
@media (min-width:1024px){
  .shr-pagenav{ position:sticky;top:109px; }
  body.admin-bar .shr-pagenav{ top:141px; }
}

/* A section landed on by an anchor clears the header and the bar above it.
   Without this the heading sits underneath both and the reader arrives in the
   middle of the previous section's photograph. */
.shr-e-section[id]{ scroll-margin-top:96px; }
@media (min-width:1024px){
  .shr-e-section[id]{ scroll-margin-top:188px; }
  body.admin-bar .shr-e-section[id]{ scroll-margin-top:220px; }
}
/* Scoped with :has() so only a page carrying the bar scrolls smoothly. */
html:has(.shr-pagenav){ scroll-behavior:smooth; }
@media (prefers-reduced-motion:reduce){
  html:has(.shr-pagenav){ scroll-behavior:auto; }
  .shr-pagenav__item > a{ transition:none; }
}

/* ==========================================================================
   SECTION 69. 1.83.30. THE TEAM PAGE'S CLOSING BAND.
   ========================================================================== */

/* Kathleen, round 3: "Team page; ... And the Ready to Discuss footer doesn't
   match the other pages."

   MEASURED on /about-us/team/: zero .shr-s-cta-band, against exactly one on
   every other page, and an Elementor section of its own running 665px where
   the site's band runs 381px. The work order had this ticked against a
   measurement of /about-us/, which is a different page from the one she named.

   chrome.php now prints the site's band here. This hides the Elementor one so
   the page does not carry two. Scoped to this page id, so no other Elementor
   section anywhere is touched. */
body.page-id-150 .elementor-element-a5ebe3{ display:none !important; }

/* ===================================================================
   70. THE HEADER TITLES SHE ASKED FOR THREE TIMES. 1.84.0
   ===================================================================

   ROUND 4, said three separate times, on Projects, on Services and on
   Journal: "Looks like all of the page header titles have been made
   smaller and changed in position. Please revert them to their previous
   size and placement across all pages."

   She is right, and both causes are mine.

   THE POSITION. 1.81.1 made the masthead a flex column so the headline
   would sit centred in the 600px band 1.81.0 fixed. But
   .shr-e-masthead__inner has carried margin:0 auto since 1.19. In a
   block layout that reads as "fill the width". As a flex item, an auto
   margin on the cross axis CANCELS STRETCH and centres the item
   instead. So the inner stopped filling the row and started
   shrink-wrapping to its own content, then sliding to the middle.

   Measured at 1440 across twelve pages before this release. The gutter
   is 112px. Titles were landing at 112, 112, 112, 112, 112, 134, 163,
   175, 210, 290, 292 and 487. The shorter the headline, the further
   right it drifted. Journal, one word, sat 375px from its own gutter.
   That is exactly "changed in position" and it is why it looked like it
   had only happened on some pages.

   THE SIZE. 1.83.1 capped the headline at clamp(34px,4.6vw,62px),
   down from clamp(2.6rem,7vw,4.75rem), which is 76px. I did it because
   "Whole Home Renovation" was breaking mid-word inside a 475px track.

   THAT CAP WAS SOLVING A PROBLEM 76px NEVER HAD. Measured this release
   with the candidate applied: "Renovation" at 76px is 393px inside a
   644px box. "Renovations" 427. "Development" 461. "Landscaping" 440.
   "Recreational" 438. "Craftsmanship," 536 inside About's 1201. Not one
   word on any of the twelve pages comes close to its box. The mid-word
   break was happening at 96px, two sizes up. I shrank the type on every
   page on the site to fix something that only bit at a size this rule
   never sets.

   So the revert is two declarations, and it is safe. No grid-column
   release, no new floor, nothing invented. Both were proven on the live
   staged site, on all twelve pages, before this file was touched.

   The 600px band and the vertical centring stay. She never complained
   about either. */

@media (min-width:1024px){
  .shr-e-masthead__inner{ margin-inline:0; width:100%; }
}

/* ---- 70.1 The crumb and the rule, on the two banners that kept them ----
   Round 2, on the Projects banner: remove the "home" text and the line in
   the banner. 1.83.1 closed it with .shr-p-masthead, which is the Projects
   masthead and nothing else. Journal carries .shr-j-masthead and kept both.
   Verified by computed style, not by markup presence: Projects hidden,
   Journal VISIBLE "Home" and VISIBLE rule. The selector above now covers
   both. The Team page is an Elementor canvas and is handled below. */

/* ---- 70.2 The Team banner ----------------------------------------------
   Same note, same round, never carried across. Team was still drawing a rule
   under "Meet the Family" and an "Our People" eyebrow above it. Every other
   banner on the site lost both in round 2. */
body.page-id-150 .shr-e-masthead .shr-e-rule,
body.page-id-150 .shr-e-masthead .shr-e-eyebrow,
body.page-id-150 .shr-e-masthead .shr-l-eyebrow{ display:none !important; }

/* ===================================================================
   71. THE CERTIFICATION MARKS, AS SHE ASKED FOR THEM. 1.86.0
   ===================================================================

   ROUND 4: "Certifications & Memberships; BC Energy Step Code logo still
   missing. I've added it below. Can we have the logos be larger, centered,
   and more spread out across the page, please."

   1.85.0 put her logo in. This is the other half of the sentence.

   MEASURED on /about-us/ at 1440 before this rule: the row is 1201px wide
   starting at the 112px gutter, justify-content is normal so every mark is
   packed against the left edge, and each one renders at exactly 84px tall
   because max-height caps them all there.

   LARGER. The cap goes to 96px. max-height never scales an image UP, so this
   only releases the marks whose files are taller than 96: HAVAN and CHBA at
   130 native, RenoMark at 138, both chambers at 187. built-green and 2-5-10
   are 96 native and land exactly on the cap. es_cert is 85 native and stays
   85, which is its own ceiling and the reason 96 is the right number rather
   than 120: past this, four of the nine would be upscaled and go soft.

   CENTERED. justify-content:center. Nine marks at this size do not fit one
   1201px line, so the row wraps, and a wrapped row packed left reads as an
   accident while a wrapped row centred reads as a decision.

   MORE SPREAD OUT. The horizontal gap goes 64px to 88px.

   AND THE STEP CODE LOCKUP. Hers is 1301x430, a 3:1 horizontal lockup among
   eight roughly square marks. MEASURED with the candidate injected on the
   live page: at the old cap it drew 254x84, and at the new one it draws
   290x96, so it rises with the rest rather than being held back by the shared
   210px width allowance. Its own 300px allowance is what lets that happen.
   It is still the widest object in the row, because it is a wordmark rather
   than a badge, but it now matches its neighbours' height instead of sitting
   under it.

   PROVEN BEFORE SHIPPING, on /about-us/ at 1440:
     justify-content  normal -> center
     gap              40px 64px -> 44px 88px
     built-green      94x84 -> 107x96   (its native size, not upscaled)
     2-5-10           101x84 -> 115x96  (its native size, not upscaled)
     es_cert          82x84 -> 83x85    (unchanged, 85 is its native ceiling)
     step code        254x84 -> 290x96
     rows             1 -> 2, centred */

@media (min-width:768px){
  [data-shr-marks]{ justify-content:center; gap:44px 88px; }
  img[data-shr-mark]{ max-height:96px; }
  img[data-shr-mark][src*="bc-energy-step-code"]{ max-width:300px; }
}

/* ---- 83. THE LOGOS, AT LAST AT A SIZE SHE CAN SEE. 1.93.0 ---------------
   R1-ABOUT-06, R2, R3-ABOUT-06, R4-ABOUT-07. Raised in every round:

     "Certifications and Memberships, I definitely feel that the individual
      organization logos should be presented here."            R1
     "Can we have the logos be larger, centered, and more spread out across
      the page, please."                                       R4

   The cap stayed at 96 for four rounds because three of the four
   certification logos WERE 96 and could not go higher: BuiltGreen 107x96,
   Energy Star 83x85, 2-5-10 Warranty 115x96, each drawn at its own native
   ceiling. Raising the number would only have stretched them.

   The files are real now (see the swap table in inc/content-sections.php),
   so the cap can move. 112 rather than a bigger number because 112 is what
   the smallest of the new files carries without being stretched, and because
   the row has to hold five of them.

   Two families in this set, and they are capped on different axes, which is
   what the old 210px allowance was reaching for. Badges are roughly square
   and take the height: BuiltGreen, Energy Star, 2-5-10, HAVAN, CHBA,
   RenoMark all draw 112 tall. Wordmarks are three times as wide as they are
   tall and take the width: Step Code, and now both Chambers, all draw 260
   wide, which lands them at 76 to 86 tall. One number each, no per-logo
   special cases.

   "Spread out across the page" is space-between: each row now runs the full
   width of the column instead of huddling in the middle of it.

   MEASURED on /about-us/ at the real 1256px column, after the swap:
     certifications  653px of logos, 201px between them
     memberships     906px of logos,  87px between them
     nothing upscaled, in either row
   Before: 595px and 689px of logos in the same column, every one 96 or less. */
@media (min-width:768px){
  img[data-shr-mark]{ max-height:112px;max-width:260px; }
  img[data-shr-mark][src*="bc-energy-step-code"]{ max-width:260px; }
  .shr-e-section [data-shr-marks]{ justify-content:space-between;gap:40px 0; }
}
/* Below 768 the row wraps, and space-between on a wrapped row pushes the last
   line apart. It stays centred there. */
@media (max-width:767px){
  .shr-e-section [data-shr-marks]{ justify-content:center; }
}

/* 83.1 THE WIDTH CAP ON A MARK HAS NEVER WORKED INSIDE A SECTION. 1.93.1

   MEASURED on /about-us/ after 1.93.0 went up: the Step Code wordmark drew
   339px wide and the North Vancouver Chamber 344px, against a 260px cap. The
   computed max-width on every mark in that row read 100%.

   Section 2685 guards against an inherited inline width arriving from markup
   the engine does not parse:

     .shr-e-section :where(figure, img, iframe, video, table, embed, object){
       max-width:100% !important; height:auto;
     }

   It is !important, and :where() gives it zero specificity, so nothing that
   sets max-width on a mark inside an editorial section has ever beaten it.
   Not the 180px base, not the 210px at 768, not the 300px written for the
   Step Code, and not the 260px above. Every one of those numbers was dead on
   this page and the row has only ever been sized by its height.

   The guard stays: it earns its place for figures and embeds. Marks step out
   of it here, because a cap of their own IS the guard for them, and because
   two of the nine are wordmarks three times wider than they are tall and the
   row cannot hold them at full height.

   Measured with this rule in place, at the 1256px column:
     certifications  653px of logos, 201px between them
     memberships     905px of logos,  88px between them
   which is what section 83 above was written to produce. */
@media (min-width:768px){
  .shr-e-section [data-shr-marks] img[data-shr-mark]{ max-width:260px !important; }
}

/* ---- 72. A LONG LEDE SETS IN TWO COLUMNS. 1.87.1 -------------------------
   Kathleen, round 3, about the service pages: "I'm disliking the intro blurb
   format as one singular column. Can we change this to be either a more
   stretched format across the page, or two columns? Whatever design you think
   is best." 1.79.0 answered that for the intro run and nowhere else.

   MEASURED on the live site after 1.87.0, at 1536px: .shr-e-section
   .shr-e-lede is capped at the 720px body measure inside a 1400px inner, so
   three sections on Retaining Walls each carried a 680px column of nothing
   beside their copy, 1053px, 1506px and 641px tall. THE STANDARD: no row has
   a hole in it.

   SPECIFICITY IS THE WHOLE TRICK HERE, and it is the lesson from 15.3 again.
   The cap comes from `.shr-e-section .shr-e-lede`, which scores 0-2-0. A bare
   `.shr-e-lede--two` scores 0-1-0 and loses silently: the first live test of
   this fix left the lede at 720px and looked, from the class list alone, as
   though it had worked. The selector below carries the section class for that
   reason. DO NOT shorten it.

   1180px and the 72px gutter and the hairline rule are not new numbers: they
   are exactly what .shr-e-prose--two has used on the intro since 1.79.0, so
   the two runs read as the same device rather than two.

   An h3 inside a lede opens an incorporated run, such as the wall systems on
   Retaining Walls. It spans both columns so the reader sees a new subject
   start, and the copy under it flows on in two.                            */
.shr-e-section .shr-e-lede--two,
.shr-s-section .shr-e-lede--two{ max-width:min(1180px,100%); }
@media (min-width:900px){
  .shr-e-section .shr-e-lede--two,
  .shr-s-section .shr-e-lede--two{
    columns:2;column-gap:72px;column-rule:1px solid rgba(90,107,120,.2);
  }
  /* 1.87.2. A PARAGRAPH IS NEVER CUT ACROSS THE GUTTER.
     1.87.1 copied break-inside:auto from the prose run, and auto is what lets
     a column end mid-sentence: the reader finishes a line on the left, and the
     rest of the sentence is at the top of the right column. Measured on the
     live page, four paragraphs were cut that way. Every block now stays whole
     and the columns balance around them. A block too tall for one column is
     still broken by the browser, which is the correct fallback and not a case
     that occurs on this site.                                               */
  .shr-e-lede--two > p{ max-width:none;break-inside:avoid; }
  .shr-e-lede--two > :is(h3,h4,ul,ol,figure,blockquote){ break-inside:avoid; }
  .shr-e-lede--two > :is(h3,h4){ break-after:avoid; }
  .shr-e-lede--two > h3{ column-span:all;margin-top:10px; }
}

/* ---- 73. AN INCORPORATED SECTION, AND A ROW OF FIVE. 1.87.2 --------------
   73.1 THE RUN.

   Round 2, on Retaining Walls: "Retaining Wall Systems; I don't think this is
   necessary, or it can be incorporated into the Approach section." 1.87.1
   incorporated it by pouring its six wall types into the Approach section's
   opening copy as h4s and paragraphs, inside a two-column box. Quentin, 30
   September: "it doesnt look good when the sentences are cut in half into the
   right side."

   Six named items are a list, not prose, and every other list of named items
   on this site is a card grid. So an incorporated section now keeps its own
   shape: a sub-heading under a short rule, its opening line at the reading
   measure, and its items as cards. Six cards, three across, two even rows.
   A card cannot be cut in half by a column break.

   The heading sits between the section h2 and the card h3 so the hierarchy
   reads at a glance: section, run, item.                                    */
.shr-s-run{ margin-top:64px; }
@media (min-width:768px){ .shr-s-run{ margin-top:88px; } }
.shr-s-run__head{ margin:0 0 28px; }
.shr-s-run__head .shr-e-rule{
  display:block;width:40px;height:2px;margin:0 0 20px;background:var(--shr-blue);
}
.shr-s-run__head :where(h3){
  margin:0;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.6rem,2.8vw,2.25rem);line-height:1.15;letter-spacing:.01em;
  color:var(--shr-harbour);max-width:24ch;text-wrap:balance;
}
.shr-bg-harbour .shr-s-run__head :where(h3){ color:var(--shr-ivory); }
.shr-s-run .shr-e-lede{ margin:0 0 44px; }

/* 73.2 NOT DONE: A ROW OF FIVE.

   Five cards in a three-up draw three, then two. The first version of this
   release laid such a grid on six tracks so the last two widened and filled
   the row. It was inert, and rightly so: section "4. The orphan rows" of this
   stylesheet already turned .shr-s-cards--three from a grid into a centred
   flex wrap for exactly this reason, on findings 6 and 8 to 11, and its note
   reads "seven items in a three-up grid leave one alone on its own row, which
   reads as a mistake rather than a set. Wrapped and centred, seven read as
   seven." Three and then two, centred, is that same device and it is a
   deliberate answer already given. It is left alone.                        */

/* ---- 74. THE SIX SERVICES, UNDER THE HEADER. 1.88.0 ----------------------
   Kathleen, round 4, on the home page: "bring it up to live under the 'What
   We Build' header and designed to look more like what Miranda had done on
   her staging site, just matching your aesthetic? Ie; icons with small blurb."

   Miranda's band is six circular line icons three across on navy. This is the
   same idea in this site's materials: the section's own chalk ground, the
   harbour line icon this stylesheet already uses for certifications and the
   footer ridgeline, the display face for the title and the body face for the
   line under it.

   Three across from 1024, two from 600, one below that. Six divides by three
   and by two, so no row ever has a hole in it at any width, which is the
   whole reason the row of four it replaces could not be made to work.

   The whole tile is the control, not the title, so the target is 300px wide
   rather than the width of a few words. Rule 15: nothing moves on its own,
   and the only thing that changes on hover is the ring and the colour.     */
.shr-build__services{
  list-style:none;margin:48px 0 0;padding:0 24px;
  display:grid;gap:44px 32px;
}
@media (min-width:600px){
  .shr-build__services{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}
@media (min-width:768px){
  .shr-build__services{ margin-top:72px;padding:0;gap:56px 48px; }
}
@media (min-width:1024px){
  .shr-build__services{ grid-template-columns:repeat(3,minmax(0,1fr));gap:64px 56px; }
}
.shr-svc__link{
  display:block;text-decoration:none;color:inherit;
  transition:color .25s ease;
}
.shr-svc__ring{
  display:flex;align-items:center;justify-content:center;
  width:64px;height:64px;border-radius:50%;
  border:1px solid rgba(8,36,58,.28);
  color:var(--shr-harbour);
  transition:border-color .25s ease,color .25s ease;
}
.shr-svc__glyph{ width:34px;height:34px;display:block; }
.shr-svc__title{
  margin:20px 0 10px;
  font-family:var(--shr-font-display);font-weight:400;
  font-size:clamp(1.25rem,1.9vw,1.5rem);line-height:1.25;
  color:var(--shr-harbour);text-wrap:balance;
  transition:color .25s ease;
}
.shr-svc__body{
  margin:0;max-width:34ch;
  font-size:17px;line-height:1.7;color:var(--shr-slate);
}
@media (min-width:768px){ .shr-svc__body{ font-size:18px; } }
.shr-svc__link:hover .shr-svc__ring,
.shr-svc__link:focus-visible .shr-svc__ring{
  border-color:var(--shr-blue);color:var(--shr-blue);
}
.shr-svc__link:hover .shr-svc__title,
.shr-svc__link:focus-visible .shr-svc__title{ color:var(--shr-blue); }
.shr-svc__link:focus-visible{ outline:2px solid var(--shr-blue);outline-offset:6px; }

/* ---- 75. TWO ABOUT SECTIONS SHE ASKED TO BE RESIZED. 1.88.1 --------------
   75.1 "Our Story; 'Thirty Years on the North Shore' can be made much
   bigger." Round 4.

   MEASURED at 1536: every section heading on About sets at 46.4px, including
   this one, so the page's opening story reads at exactly the same weight as
   Certifications and Memberships. It is the first thing under the banner and
   it carries 106 characters and one wide photograph; it is a title card, not
   a section like the others.

   It goes to 64px at 1536. The banner above it is 76px, so the hierarchy is
   banner, then story, then the rest of the page, and the story no longer
   competes with sections it should be introducing.                         */
#sec-thirty-years-on-the-north-shore .shr-s-head :where(h2){
  font-size:clamp(2.5rem,5vw,4rem);
}

/* 75.2 "Supporting the Next Gen; can the image next to this blurb be made
   bigger, please." Round 4.

   MEASURED at 1536: the copy column runs 667px and the media column 477px,
   so the photograph sets at 477x318 beside 968 characters of copy.

   The columns are evened. The photograph goes to 572x381, 20 per cent wider
   and 44 per cent more area, and the copy still sets at about 55 characters
   a line, inside the comfortable range for this audience.

   WHAT I DID NOT DO, AND THE CHECK THAT STOPPED ME. The first version of this
   also released the figure from its 3:2 frame, on the assumption it was
   cropping a 4:3 source. IT IS NOT. Attachment 4084 measures 2560x1707, which
   is exactly 3:2, so the frame matches the photograph and nothing was ever
   being cropped. Releasing it to aspect-ratio:auto also collapsed the figure
   to 572x0 while the image was still lazy, which would have shifted the page
   on every load. Both were caught by measuring the rendered box instead of
   trusting the class name. The frame stays.

   The media column is still taller than the photograph, because a landscape
   photograph beside 968 characters cannot fill it without being cropped to a
   portrait, and cropping a crew photograph to portrait cuts people out of it.
   That is a limit of the source, recorded here rather than papered over.   */
@media (min-width:1024px){
  #sec-supporting-the-next-generation-of-builders .shr-e-stack{
    grid-template-columns:repeat(2,minmax(0,1fr));
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   76. THE SECOND COMMUNITY PHOTOGRAPH IN PROUDLY NORTH SHORE
   1.89.0

   Kathleen, round 4: "Proudly North Shore; this section looks great! Let's
   add another community image in this area."

   WHAT HER RED BOX IS ACTUALLY MARKING, MEASURED. The section is a 1400px
   prose box, two columns of 592px with a 72px gap:

     column 1   heading (spans both), two paragraphs, ending at y=640
     column 2   the existing 340px portrait, a sub-head, a list, to y=1187

   Column 1 is EMPTY from y=640 to y=1187. That 592 by 547 hole is the area
   she drew a box around, and it is an S3 failure in its own right: no section
   is half empty.

   WHY THERE IS NO column-span HERE. My first version spanned the companion
   across both columns as a band under the copy. That reads well but it does
   not fill the hole, it sits below it, and the hole is the actual complaint.
   The photograph is instead spliced into the flow before the existing figure
   (see shr_sections_prose_companion), which lands it in column one directly
   under the paragraphs. VERIFIED in the live DOM at that insertion point:
   the companion resolved to column 1 under both paragraphs, and the columns
   came back at 1055px against 1196px where they had been 640 against 1187.

   The figure keeps its frame and is never drawn above its file: at the 592px
   column it sets at 592x395 from a 1920x1141 original.                     */

.shr-e-companion{ margin-top:28px; }
.shr-e-companion img{ display:block;width:100%;height:auto; }
@media (min-width:1024px){
  .shr-e-prose--two > .shr-e-companion{
    break-inside:avoid;
    -webkit-column-break-inside:avoid;
    margin:28px 0 0;
    max-width:100%;
  }
}
@media (max-width:1023px){
  .shr-e-companion{ margin-top:24px; }
}

/* ─────────────────────────────────────────────────────────────────────────
   77. THE ABOUT BANNER TITLE, ON ONE LINE
   1.89.1

   Round 3: "I'd like the Quality, Expertise, Craftsmanship, and Results in
   one line across the banner."   Asked again in round 4 about the separators,
   which 1.85.0 answered with her pipes. The ONE LINE half was never done, and
   Quentin caught it on the 1.89.0 build: the title breaks after "Expertise |",
   which leaves a separator dangling at the end of the first line.

   WHY IT COULD NEVER FIT, MEASURED. `.shr-s-masthead h1` carries
   max-width:18ch. The title is 45 characters. At 64px it needs 1282px and the
   cap gives it 921.6px, so it wrapped at every window width, including the
   1900px one she and Quentin are looking at. The cap, not the window, was the
   whole problem.

   WHY THIS IS A CONTAINER QUERY AND NOT A vw FORMULA. My first attempt sized
   the type against the viewport and it overflowed the box by 40px, because
   the h1's real track is not the viewport: the section takes 40px of padding
   each side and `__inner` takes another 56px each side, so the track is the
   inner content box, 112px narrower again. Measuring the container directly
   removes every one of those constants and cannot drift if the padding is
   ever retuned.

   THE RATIO. Measured on the live page at five sizes: this face sets the
   45-character title at 20.03 to 20.30 times the font size. 20.4 is that
   worst case plus a margin, so the line always lands inside the track.

   PROVEN at five track widths before this was written, 1288 down to 640:
     1288 -> 63.1px, text 1264, one line
     1100 -> 53.9px, text 1080, one line
      900 -> 44.1px, text  883, one line
      735 -> 36.0px, text  721, one line
      640 -> 31.4px, text  628, one line
   No clipping and no overflow at any of them. At the 1288px track a 1900px
   window gives, the type is 63.1px, which is the designed 64px in all but
   name, so this costs nothing at the size she reviews at.

   Desktop only. Below 1024px the masthead keeps its existing treatment, so
   the type never gets driven down to a phone-sized headline for the sake of
   one line.                                                                */

@media (min-width:1024px){
  body.page-id-16 .shr-e-masthead__inner{
    container-type:inline-size;
  }
  body.page-id-16 .shr-e-masthead__inner > h1{
    max-width:none;
    white-space:nowrap;
    font-size:min(4rem, calc(100cqi / 20.4));
  }
}

/* ===================================================================
   78. THE WHITE BANNER COMES OFF THE CERTIFICATIONS. 1.90.2
   R2-ABOUT-08, R3-ABOUT-06, R4-ABOUT-07, asked in rounds 2, 3 and 4:
   "the white banner around the affiliations is still present."

   Section 56 made the whole section pure white so that the opaque
   white baked into most of the logo files would have nothing to show
   against. MEASURED 30 September, every file loaded to a canvas and
   its pixels counted: built-green 71% opaque white, 2-5-10 warranty
   72%, chba 80%, RenoMark 48%, North Vancouver Chamber 86%, West
   Vancouver Chamber 87%. Only HAVAN and BC Energy Step Code carry an
   alpha channel.

   It worked, and it IS the banner she is looking at. Measured on the
   rendered page: that section computed rgb(255,255,255) while every
   other shr-bg-paper section on About computed rgb(240,235,224). A
   white band across a cream page, wrapped around the affiliations.

   mix-blend-mode:multiply makes a white pixel take the colour behind
   it, which is the actual repair and needs no new artwork. But
   blending stops at the nearest stacking context, and GSAP leaves
   transform and will-change on every .reveal-item, which makes one.
   So the ground must be painted INSIDE that group, on the row itself,
   which is what the change to section 51 above does.

   PROVEN ON THE RENDERED PAGE BEFORE SHIPPING. With the ground on the
   section alone, all six white rectangles were plainly visible on the
   cream. With it on the row, none is, and the logos keep their own
   colours: multiply against #f0ebe0 moves a colour by less than 8%.

   Dark surfaces are untouched. On harbour a multiply would turn every
   white logo black, so section 27's ivory plate still rules there.
   =================================================================== */
:root           { --shr-ground:var(--shr-chalk); }
.shr-bg-chalk   { --shr-ground:var(--shr-chalk); }
.shr-bg-paper   { --shr-ground:var(--shr-paper); }
.shr-bg-ivory   { --shr-ground:var(--shr-ivory); }
/* A dark surface has no ground to give: its marks already sit on their own
   ivory plate from section 27, and a light row behind them would be a band
   across the navy. Before 1.90.2 the row was transparent here because the
   white-out rule made it so; this keeps it transparent now that rule is gone. */
.shr-bg-harbour { --shr-ground:transparent; }
.shr-e-masthead { --shr-ground:transparent; }

.shr-e-section:not(.shr-bg-harbour) [data-shr-marks] img[data-shr-mark]{
  mix-blend-mode:multiply;
}
/* A mark carries no width or height attribute, so before it loads it is a 0x0
   box. 1.90.3 makes marks eager, which is the real fix; this is the floor
   under it, so a slow or failed mark still holds its place in the row rather
   than closing the gap and shifting the eight beside it. */
[data-shr-marks] img[data-shr-mark]{ min-width:72px;min-height:48px; }
/* A plate is a plate. Where a mark already sits on its own ivory ground,
   multiplying it twice would grey it. */
.shr-bg-harbour img[data-shr-mark],
.shr-e-masthead img[data-shr-mark]{ mix-blend-mode:normal; }

/* ===================================================================
   79. THE SAME WHITE BANDS, ON THE HOME PAGE. 1.91.0
   R2-HOME-09, her round 2: "No white boxes behind award or
   certification logos ANYWHERE."

   Section 78 took the band off About. This is the other half of the
   same note and I had it recorded as never asked for. It was asked
   for, and the word is anywhere.

   MEASURED on the rendered home page 30 September: .shr-recognition
   and .shr-certs both computed rgb(255,255,255) on a body of
   rgb(247,245,240). Two white bands, one above the other, on a cream
   page, wrapped around the award and certification logos.

   The 1.71.2 note above says two goes at multiply did not clear the
   row and the ground was matched to the files instead. The blend is
   already declared on .shr-plate__mark; what it never had was a
   backdrop inside its own group. .shr-cert and
   .shr-recognition__bodies ARE the transformed reveal-items, which is
   what 1.71.1 worked out and then solved with white. The same
   mechanism works with chalk, and chalk is the page.

   So the bands take the body colour, the plates inside the group take
   it too, and multiply drops the white baked into the files against
   it. No band, no boxes, no seam between the two credentials
   sections, and the marks keep their own colours: multiply against
   #f7f5f0 moves a colour by under 4%.
   =================================================================== */
.shr-certs,
.shr-certs .shr-cert{ background-color:var(--shr-chalk) !important; }
.shr-recognition{ background-color:var(--shr-chalk); }
.shr-recognition__bodies{ background:var(--shr-chalk) !important; }


/* ---- 80. CLIENT STORIES GETS A TITLE. R2-HOME-11 ------------------------
   Her round 2 note, in full:

     "Client Stories; Can this section be in navy? And the title text larger?"

   The navy landed. The title did not, and the reason it did not is that
   there was no title: "Client Stories" was a 12px eyebrow in a section with
   no heading element in it at all, so there was nothing to make larger. It
   is an h2 now and the home page's single section-title rule, which already
   names `.shr-quotes h2`, takes it to 76px from 1024px up. This block is the
   base below that and the colour, because the band is navy. */
.shr-quotes__title{
  margin:0;
  font-family:var(--shr-font-display);
  font-weight:400;
  font-size:clamp(2rem,4.4vw,3.4rem);
  line-height:1.1;
  letter-spacing:.01em;
  color:var(--shr-ivory);
  text-transform:none;
  text-wrap:balance;
}


/* ---- 81. WHAT WE BUILD, ON NAVY. R4-HOME-03, R3-HOME-02, R2-HOME-08 ------
   Asked three rounds running:

     R2  "Still not a fan of the What We Build section. Maybe we should just
          incorporate this into the Build Around the Site section?"
     R3  "this either needs to be a more substantial section or completely
          removed. It's very lackluster still and seems out of place."
     R4  "I like the change you've made of having our services listed here.
          This is a great move in the right direction! Is it possible to bring
          it up to live under the 'What We Build' header and designed to look
          more like what Miranda had done on her staging site, just matching
          your aesthetic? Ie; icons with small blurb."

   Round 4 carried two screenshots. The one captioned "The specific section"
   was this band as it stood: cream, the serif heading at the left and a small
   grey paragraph away at the right. The one captioned "The other staging site
   suggestion" was Miranda's: navy, six circular white line icons three
   across, a white title and a two line blurb on each.

   1.88.0 delivered the icons and the blurbs and left the band cream, which is
   the picture she was pointing away from. This is the other half.

   81.1 The band. It runs the full width and carries its own padding, so
   `.shr-build` itself no longer pads: the brief pads, and the inner that
   holds the three photographic bands pads. No viewport-width breakout, no
   negative margins, nothing that can overflow sideways at a scrollbar.

   The padding is the page's own band scale, --shr-band / -md / -lg, not new
   numbers. Section 73 put the home page on one vertical rhythm after it had
   been running at five at once, and a navy band pasted in at 64/128 would be
   the sixth. */
.shr-build{ padding:0; }
@media (min-width:768px){ .shr-build{ padding:0; } }

.shr-build__brief{
  background-color:var(--shr-harbour);
  color:var(--shr-ivory);
  padding:var(--shr-band) 0;
}
@media (min-width:768px){ .shr-build__brief{ padding:var(--shr-band-md) 40px; } }
@media (min-width:1024px){ .shr-build__brief{ padding:var(--shr-band-lg) 40px; } }
.shr-build__brief-inner{ position:relative;z-index:10;max-width:1400px;margin:0 auto; }

.shr-build__inner{ padding:var(--shr-band) 0; }
@media (min-width:768px){ .shr-build__inner{ padding:var(--shr-band-md) 40px; } }
@media (min-width:1024px){ .shr-build__inner{ padding:var(--shr-band-lg) 40px; } }

/* The list used to be spaced off the tiles by its own top margin while both
   sat in one padded section. They are two bands now and the padding on each
   does that job, so the margin would be counted a second time: at 1024 it
   would put 384px between the last tile and the first photograph. */
.shr-build__list{ margin-top:0; }

/* 81.2 THE HOLE IN THE TOP ROW. Two equal columns with the paragraph pushed
   to the far right left roughly a third of that row empty between them, and
   that row is the screenshot she sent. The heading and the paragraph stack at
   the left now, the paragraph on a 54ch measure under it. Nothing is pushed
   anywhere and there is no gap to explain. */
.shr-build__head{ padding:0 24px; }
@media (min-width:768px){
  .shr-build__head{ grid-template-columns:1fr;align-items:start;gap:24px;padding:0; }
  .shr-build__head p{ max-width:54ch;justify-self:start; }
}
.shr-build__head h2{ color:var(--shr-ivory); }
.shr-build__head p{ color:rgba(251,250,247,.86);font-size:17px; }
@media (min-width:768px){ .shr-build__head p{ font-size:18px; } }

/* 81.3 The six tiles, read for navy. Miranda's icons are white rings; ours
   are the same rings the chalk band used, re-inked. The hover colour moves
   off --shr-blue, which is a link blue mixed for a pale ground and goes muddy
   on harbour, to plain ivory: on navy the ring and the title simply come up
   to full strength. */
.shr-build__brief .shr-svc__ring{
  border-color:rgba(251,250,247,.38);
  color:var(--shr-ivory);
}
.shr-build__brief .shr-svc__title{ color:var(--shr-ivory); }
.shr-build__brief .shr-svc__body{ color:rgba(251,250,247,.82); }
.shr-build__brief .shr-svc__link:hover .shr-svc__ring,
.shr-build__brief .shr-svc__link:focus-visible .shr-svc__ring{
  border-color:var(--shr-ivory);
  color:var(--shr-ivory);
  background-color:rgba(251,250,247,.10);
}
.shr-build__brief .shr-svc__link:hover .shr-svc__title,
.shr-build__brief .shr-svc__link:focus-visible .shr-svc__title{ color:var(--shr-ivory); }
.shr-build__brief .shr-svc__link:focus-visible{ outline:2px solid var(--shr-ivory);outline-offset:6px; }


/* ---- 82. TWO THINGS SEEN ON THE PAGE AFTER 1.92.0 -----------------------

   82.1 THE CLIENT STORIES CONTROL WAS PAINTED NAVY ON NAVY.

   The section carries eight testimonials and shows one at a time, with a
   segmented bar underneath saying how many there are and how long is left on
   the current one. That bar was marked `shr-segbar--dark`, which is the
   variant for a LIGHT ground: track rgba(8,36,58,.18), fill --shr-harbour.
   When R2-HOME-11 turned the band navy the modifier was never changed, so
   both the track and the fill became harbour on harbour and the control
   disappeared. What a visitor saw was one quote, no bar, and nothing to say
   there were seven more.

   It had been invisible since the band went navy. The 76px title in 1.91.3
   only pushed it further down the screen, which is what made it noticeable.

   The modifier is off the markup now. These two rules are the guarantee: a
   bar inside this band is light-ink whatever class anyone puts on it later. */
.shr-quotes .shr-segbar__seg::before{ background-color:rgba(251,250,247,.35); }
.shr-quotes .shr-segbar__seg span{ background-color:var(--shr-ivory); }

/* 82.2 "CRAFTSMANSHIP" WAS BREAKING IN HALF.

   Her note, twice, R2-HOME-07 and again R3-HOME-01:

     "The Quality, Expertise, Craftsmanship, Results text under Mark's quote
      is still too small"

   It was made larger, to clamp(40px, 4.5vw, 60px). The row is four EQUAL
   columns, so at 1536 each one is 310px. Measured in the page at 60px:
   Quality 200, Expertise 261, Craftsmanship 408, Results 201. Craftsmanship
   needs 408 and had 310, and `overflow-wrap:break-word` did what it is for
   and split it mid-word into "Craftsman" and "ship".

   The four words together are 1068px and the row is 1361px. THE ROW WAS
   NEVER TOO NARROW. The equal columns were. So the fix is not to shrink the
   type she asked twice to enlarge; it is to stop forcing the longest word
   into a quarter of the row.

   Columns are max-content now and the row distributes them, and the size is
   tied to the row with a container query rather than to the viewport, so it
   is the row's real measurement that governs and not an assumption about
   gutters. Measured on the page: the row is the viewport less the scrollbar
   less 160px of gutters, capped at 1400.

   The honest arithmetic, from the measured widths. Four words plus three
   40px gaps need 18 x the type size plus 120px. At a 1025px row, which is
   what a 1200px viewport gives, the most that fits is 50.3px. The old
   4.5vw put 54px there and it DID NOT FIT: that is the whole reason the
   word was being broken. So below about 1440 the type is now a little
   smaller than the number that was set, and every word is whole. From 1440
   up, where 60px genuinely fits, it is exactly the 60px that shipped.

   A whole word at 48px reads; "Craftsman" over "ship" does not read at any
   size. white-space:nowrap is the belt: whatever else changes later, one of
   these four words can never be cut in half again. */
.shr-pillars__grid{ container-type:inline-size; }
.shr-opening .shr-pillar h2,
.shr-pillar h2{
  white-space:nowrap;
  overflow-wrap:normal;
  hyphens:none;
}
@media (min-width:1200px){
  .shr-pillars__grid{
    grid-template-columns:repeat(4,max-content);
    justify-content:space-between;
  }
  .shr-opening .shr-pillar h2,
  .shr-pillar h2{ font-size:min(60px, 5.35cqw - 6.6px); }
  /* The sub line under each word on /why-shakespeare-homes/ is a phrase, not
     a word, so it may wrap. It must not be what decides the column width:
     "EIGHTY-SEVEN INDUSTRY AWARDS" is wider than "Results" and it pushed the
     row 51px past its container at a 980px row. width:0 keeps it out of the
     intrinsic measurement, min-width:100% gives it the column back to wrap
     inside. */
  .shr-pillar p{ width:0;min-width:100%; }
}

/* 82.3 The same row on /why-shakespeare-homes/ had 40px gutters where the
   home page has 80. With the four words distributed across the full row,
   "Results" finished 40px from the edge of the viewport and the contact rail
   is 52px wide and fixed to that edge, so the last word sat underneath it.
   Centred text in a quarter-width column had been hiding that. Same gutters
   as the home row now, which clears the rail by the same 28px. */
@media (min-width:768px){
  .shr-l-why__pillars{ padding-left:80px;padding-right:80px; }
}

/* ---- 84 HER PROSE ON THE LEFT, HER DETAILS ON THE RIGHT. 1.95.0 ----------
   Round 4, marked up on a screenshot of Sandringham: the SQUARE FOOTAGE /
   MAIN LEVEL / LOWER LEVEL rows and ARCHITECTURAL STYLE boxed in red at the
   foot of the LEFT column, with an arrow carrying them to the top of the
   RIGHT column above FEATURES OF THE BUILD/RENO. "Please have these sections
   separated and grouped accordingly."

   `columns:2` balanced the row by HEIGHT, so whether a specification row
   landed beside the prose or under it was decided by how long her paragraphs
   were. This is a grid instead: two real columns, prose in one, every detail
   in the other, in the order she wrote them. It cannot drift back.

   The rule between the columns is a border rather than `column-rule`, which
   only exists in a flow. It is drawn on the detail column so it stops at the
   taller of the two rather than running past the end of the content. */

@media (min-width:1024px){
  .shr-p-story__body--split{
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    column-gap:72px;
    align-items:start;
  }
  .shr-p-story__body--split > .shr-p-story__lede{
    grid-column:1 / -1;
    max-width:46ch;
    margin-bottom:1.4em;
  }
  .shr-p-story__body--split .shr-p-story__detail{
    padding-left:72px;
    margin-left:-72px;
    border-left:1px solid rgba(90,107,120,.2);
  }
  /* The first thing in each column starts on the same line as the other. */
  .shr-p-story__body--split .shr-p-story__prose > p:first-child,
  .shr-p-story__body--split .shr-p-story__detail > *:first-child{ margin-top:0; }
  .shr-p-story__body--split .shr-p-story__prose > p{ max-width:none; }
  /* Her specification rows head the detail column, two across, so the four
     Sandringham rows read as one block rather than a four-across ribbon. */
  .shr-p-story__body--split .shr-p-story__specs{
    grid-template-columns:repeat(2,minmax(0,1fr));
    margin-top:0;
  }
}

/* Below the split, one column: prose, then details, in her order. */
@media (max-width:1023px){
  .shr-p-story__body--split .shr-p-story__detail{ margin-top:1.6em; }
}

/* ---- 85 THE HAVAN WORDMARK, AT THE WEIGHT OF ITS NEIGHBOURS. 1.97.0 ------
   Quentin: "can we increase the havan logo a bit so it matches the size of
   the others."

   MEASURED by reading each file's pixels for the bounding box of its ink,
   then working out how tall that ink draws inside the row's 88px cap:

     RenoMark 88px   Energy Star 85px   BuiltGreen 77px
     2-5-10   71px   CHBA        64px   HAVAN      30px

   A max-height caps the FILE, not the mark inside it. HAVAN was 149x45 of
   ink in a 165x130 file, so it drew at about a third of RenoMark beside it.
   4797 is that mark trimmed to its ink and resampled 3x.

   Trimmed, it is a 3.12:1 wordmark, so a height cap is the wrong handle: at
   88px tall it would draw 275px wide and overpower the row. It is capped on
   WIDTH instead, at the figure that gives it the same drawn AREA as its
   neighbours, which is how a wide wordmark is balanced against a square
   badge. The six marks then land within a narrow band:

     BuiltGreen 10,120   2-5-10 9,504   RenoMark 8,976
     HAVAN       8,745   CHBA   7,920   Energy Star 7,568

   On the About row the same file is capped at 260px by the existing wide-mark
   rule, which puts it with the Step Code and the two chamber wordmarks at
   roughly 83px tall. A mark is the same mark wherever it appears. */

/* 85.1 THE GUARD AT 2685 HAS NOW CAUGHT THREE WIDTH CAPS. 1.98.0

   MEASURED on the live page after 1.97.0 shipped: HAVAN drew 213px wide, not
   the 165px written for it, and the computed max-width on the mark read 100%.

   Section 2685 guards against an inherited inline width:

     .shr-e-section :where(figure, img, iframe, video, table, embed, object){
       max-width:100% !important; height:auto;
     }

   `:where()` contributes NOTHING to specificity, but `!important` still wins,
   so that rule beats any ordinary max-width written for an image inside a
   section. It has now silently cancelled three of them: the 300px written for
   the Step Code, the 260px of 1.93.0, and this one. 1.93.1 fixed the first two
   the same way this fixes the third.

   The lesson, written down because it keeps costing a release: ANY width cap
   on an image inside .shr-e-section has to carry !important, and has to be
   MEASURED on the rendered page rather than read back from the source.

   165px is the width at which this 3.12:1 wordmark draws the same AREA as the
   square badges beside it. certtest.php asserts the !important is present. */

.shr-certs .shr-cert img[src*="havan"]{ max-width:165px !important; }
@media (max-width:480px){ .shr-certs .shr-cert img[src*="havan"]{ max-width:60vw !important; } }

/* ---- 86 THE AWARDING BODIES ROW, MEASURED ON THE RENDERED PAGE. 1.102.0 --

   1.101.0 wrote caps that did nothing: HAVAN drew 55x17 and CHBA 55x53 where
   190x61 and 107x105 were intended. The fixture passed the whole time because
   it did arithmetic on numbers I had typed in rather than reading the page.
   Everything below is a figure MEASURED on the live rendered row.

   TWO CAUSES, BOTH INVISIBLE FROM THE SOURCE OF THIS SECTION.

   1. A FLEX-ERA RULE, 67 RULES DEEP. This row has been rebuilt many times and
      every layer is still live. At line 7334:

        .shr-recognition__bodies > *{ flex:1 1 calc(25% - 18px);
                                      max-width:calc(25% - 18px); }

      Written when the row was a flex row across the full band. Inside the new
      four-column grid that 25% resolves against the 290px COLUMN, so every
      child was capped at 54.5px. Measured: plate 55px, mark 55px, and the
      Ovation wordmark 55px wide too, which is how a text item ended up the
      same width as a logo.

   2. WORDPRESS sizes="auto". The two marks that collapsed had a srcset; the
      one that rendered correctly (GeorgieAward.jpg) had none. WP 6.7 writes
      sizes="auto, (max-width: 459px) 100vw, 459px", and `auto` makes the
      browser take the element's LAYOUT width to pick a source. In a
      shrink-to-fit plate that is circular, and it settles tiny. Proved by
      removing the srcset on the live page: the mark went from 55px to exactly
      the 190px cap.

      So each mark is given an EXPLICIT width rather than a max-width. A
      definite width resolves sizes="auto" and removes the circularity.

   THE SIZES. Each file's ink box was read pixel by pixel, and the width set is
   the one that brings its DRAWN INK AREA to about 11,000, which is the only
   way four shapes this different read as one set. Verified on screen:

     HAVAN    ink 3.285:1   190 x 61   ink 186 x 57   area 10,558
     Georgie  ink 0.908:1   101 x 110  ink 100 x 110  area 10,990
     CHBA     ink 1.022:1   107 x 105  ink 106 x 104  area 10,955

   On a phone the row is two columns of about 163px, where a 190px mark
   overflows. Measured at that width too: 140 / 74 / 78, areas 5,732, 5,900
   and 5,822.

   The hairline under the Ovation wordmark (sections 5306 and 7394) is off: it
   existed to stop one lone wordmark reading as a logo that failed to load, and
   under a two-line lockup it reads as a stray rule. */

.shr-plate--bare{
  background:none;border:0;border-radius:0;box-shadow:none;
  padding:0;min-height:0;
}
.shr-recognition__bodies{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  align-items:center;justify-items:center;
  gap:40px 16px;
}
/* Undo the flex-era sizing so the grid is the only thing laying this out. */
.shr-recognition__bodies > *{
  flex:none !important;
  max-width:none !important;
  width:auto !important;
  min-width:0;
}
.shr-recognition__bodies .shr-plate{ width:auto !important;min-height:0 !important; }
.shr-recognition__bodies .shr-plate__mark{
  max-height:none !important;
  max-width:100% !important;
  height:auto !important;
  object-fit:contain;
}
.shr-recognition__bodies .shr-plate__mark[src*="havan"]{ width:140px !important; }
.shr-recognition__bodies .shr-plate__mark[src*="eorgie"]{ width:74px !important; }
.shr-recognition__bodies .shr-plate__mark[src*="canadian-home-builders"]{ width:78px !important; }

@media (min-width:768px){
  .shr-recognition__bodies{ grid-template-columns:repeat(4,minmax(0,1fr));gap:0 56px; }
  .shr-recognition__bodies .shr-plate__mark[src*="havan"]{ width:190px !important; }
  .shr-recognition__bodies .shr-plate__mark[src*="eorgie"]{ width:101px !important; }
  .shr-recognition__bodies .shr-plate__mark[src*="canadian-home-builders"]{ width:107px !important; }
}
@media (min-width:1200px){
  .shr-recognition__bodies{ gap:0 80px; }
}

/* Ovation, set as a mark rather than a line of text. */
.shr-recognition__bodies .shr-plate--word{
  background:none;border:0;padding:0;min-height:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  font-family:var(--shr-font-display);font-weight:400;
  line-height:1.02;letter-spacing:.005em;
  color:var(--shr-harbour);text-align:center;
}
.shr-recognition__bodies .shr-plate--word::before,
.shr-recognition__bodies .shr-plate--word::after{
  content:none !important;display:none !important;
}
.shr-recognition__bodies .shr-plate__line{
  display:block;font-size:clamp(1.3rem,2.4vw,1.85rem);
}
.shr-recognition__bodies .shr-plate__line + .shr-plate__line{
  font-size:clamp(1.05rem,1.9vw,1.45rem);
  letter-spacing:.12em;text-transform:uppercase;
  margin-top:.22em;color:var(--shr-slate);
}

/* ---- 87 THE ABOUT PANEL IN THE HEADER. 1.99.0 ---------------------------
   Nine destinations where Services has nine, so it uses the same panel the
   Services item already uses and needs no geometry of its own. The one rule
   it does need: an anchor link inside the panel must not be mistaken for a
   page link, so the entry that leaves the page keeps its arrow and the rest
   read as sections. */

.shr-nav__panel .shr-nav__sub{ white-space:nowrap; }

/* ---- 88 THE FOUR PILLARS, READ AS ONE LINE. 1.101.0 ---------------------
   Quentin: "I think we can make this nicer to look, like a line under each
   word or something so it looks better."

   A RULE UNDER EACH WORD CONFLICTS WITH HER ROUND 2, so it is not what this
   does. Her words, verbatim:

     "Quality, Expertise, Craftsmanship, Results; centered, larger font size,
      REMOVE THE LINES ABOVE, and the smaller text below."

   She asked twice for that block to be stripped of everything except the four
   words, and a third time (round 3) to make them bigger: "still too small".
   Adding rules back is the one change on this block she has actually ruled
   out.

   What she DID ask for is a separator, in round 4, for the About banner:

     "Landing banner title; better, but I'd like it to read like
      Quality | Expertise | Craftsmanship | Results"

   So the home block gets her own device. It is her separator, from her email,
   and it makes the four words read as one statement instead of four stranded
   words spread over 1,361 pixels, which is what MEASURED at 1536px. It also
   makes the home block and the About banner carry the same line, which they
   did not before.

   1.103.0. HOW IT IS CENTRED, AND WHY THE FIRST ATTEMPT COULD NOT BE.

   1.101.0 drew the pipe with ::before at left:0 and a hand picked
   translateX(-24px). This row is justify-content:space-between, so the gap
   between two words is FREE SPACE: it is whatever is left after the four
   words are laid out, and it changes with every viewport width. MEASURED at
   1536px on 1.102.0:

     Quality  . Expertise       gap 97.6   pipe 24.8px right of centre
     Expertise . Craftsmanship  gap 97.5   pipe 24.8px right of centre
     Craftsmanship . Results    gap 97.5   pipe 24.8px right of centre

   The gaps were even. Every pipe was off centre by the same amount, because
   -24px is half of nothing in particular. Half of that gap is 48.75px, and
   at a 1025px row it is 27.7px. NO FIXED OFFSET CAN BE RIGHT AT MORE THAN
   ONE WIDTH, and CSS cannot read a space-between gap, so there was no number
   to put there.

   So the separator stopped being a pseudo element and became a real item in
   the row. In a space-between row the gap to its left and the gap to its
   right are the SAME gap, by definition of space-between. It is centred by
   the layout, not by arithmetic, and it stays centred at any width.

   MEASURED on the rendered page, exactly this CSS, old rule removed:

     row 1025 (vp 1200)  gaps 55.45  off 0.00 0.00 0.00
     row 1075 (vp 1250)  gaps 56.21  off 0.00 0.00 0.00
     row 1125 (vp 1300)  gaps 57.01  off 0.00 0.00 0.00
     row 1191 (vp 1366)  gaps 58.09  off 0.00 0.00 0.00
     row 1265 (vp 1440)  gaps 65.60  off 0.00 0.00 0.00
     row 1361 (vp 1536)  gaps 97.55  off 0.00 0.00 0.00

   The words did not move: first word still at 80, last still at 1440.8, row
   still 96.8 tall, type still 60px. Only the separator moved.

   It is marked up as a word, so it takes the words' face, size, line height
   and 32px top margin from the rules above and sits on their baseline with
   nothing hard coded here. MEASURED: separator ink 311.1 to 391.1, word ink
   311.1 to 391.1.

   SCOPED TO THE HOME ROW. The old selector matched every .shr-pillars__grid,
   so it also put pipes on /why-shakespeare-homes/, where the pillars keep
   their hairline, tick and caption and the pipe landed up at hairline level
   reading as a stray tick. She never asked for a separator there. Her pipe
   request, R4-ABOUT-01, is the About landing banner, and that banner already
   reads Quality | Expertise | Craftsmanship | Results as literal text. */

/* Below 1200 the four words stack two by two, where a separator between them
   would mean nothing, so it is not drawn. A display:none grid item leaves the
   track list alone, so the two column layout still sees exactly four items.
   VERIFIED on the rendered page: four visible items in two rows of two, and
   the three hidden items are all separators. */
.shr-pillar--pipe{ display:none; }

@media (min-width:1200px){
  /* grid-auto-flow keeps this true for any number of words, so adding a
     fifth pillar could never drop a separator onto its own line. */
  .shr-opening .shr-pillars__grid{
    grid-template-columns:none;
    grid-auto-flow:column;
    grid-auto-columns:max-content;
    column-gap:0;
  }
  .shr-opening .shr-pillars__grid .shr-pillar--pipe{ display:block; }
  .shr-opening .shr-pillars__grid .shr-pillar--pipe h2{
    color:var(--shr-blue);
    opacity:.42;
  }
}

/* ---- 89 THE SUPPORTING THE NEXT GENERATION PHOTOGRAPH. 1.107.0 ----------
   Round 4, About: "Supporting the Next Gen; can the image next to this blurb
   be made bigger, please."

   MEASURED on the live page at 1536px: that block is a two column stack of
   572px and 572px, and the photograph drew 572x381. The two other
   photographs set beside copy on the same page draw 477x636 and 544x363, so
   the one she asked to grow was the smallest of the three by area.

   The COLUMN SPLIT is weighted towards the picture rather than the figure
   being stretched, so the photograph keeps its own 3:2 crop and nothing is
   upscaled past its natural size. MEASURED with exactly this rule applied to
   the live page: 686x458, an area 44 per cent larger, which puts it level
   with the other two. The reading column keeps 458px, still a comfortable
   measure for a short blurb.

   Scoped to that section's own anchor id, so no other stack on the site can
   move. The id is generated from her own heading by shr_sections_anchor_id()
   and is the same one the About shortcut nav links to. */
@media (min-width:1024px){
  #sec-supporting-the-next-generation-of-builders .shr-e-stack{
    grid-template-columns:minmax(0,0.8fr) minmax(0,1.2fr);
  }
}


/* ---- 90 MEET THE FAMILY IS ONE SET, NOT A HIERARCHY. 1.108.0 ------------
   Quentin, 1 October, looking at the About page: "make the top row of
   headshots the same size as the bottom row but have the row with the 3
   headshots more spaced evenly instead of larger than the second row. Makes
   it seem the lower row of headshots arent as important."

   He is right, and it was mine. MEASURED at 1536px: the first three drew
   397x529 and the other four drew 290x387, so the top three were 87 per cent
   larger by area. That happened for no better reason than three items sharing
   a row that four share below. Nothing Kathleen wrote asks for a senior row.
   The three then four shape is just her own ordering of the team, and the
   sizes turned it into a ranking nobody intended.

   SO THE ORDER AND THE SHAPE ARE UNTOUCHED, and only the size gap goes.
   Every portrait is now the width the bottom row already used, and the three
   on top are spread across the row instead of stretched to fill it.

   A 24 COLUMN GRID IS WHAT MAKES THAT EXACT. The bottom row is four cells of
   six columns. The top row is three cells of six columns pinned at columns 1,
   10 and 19, so the outer two sit exactly above the outer two below and the
   middle lands centred between them. MEASURED at 1536px: photographs at 125,
   608 and 1091 on top against 125, 447, 769 and 1091 below, every one 290
   wide.

   WHY NOT JUST GIVE THE FIRST THREE THE SAME FLEX BASIS. Because then four of
   them fit on the first row, which lifts Jesse into the leadership row and
   changes what the grouping says. Forcing the break with a pseudo element
   does work, but it spends a 48px row gap on an invisible item: MEASURED, it
   pushed the second row down by exactly that.

   MEASURED ACROSS THE RANGE with this rule: 1536, 1280, 1024, 900 and 800 all
   render three then four, every portrait identical in size, no overlap, and
   the first and last aligned to the row edges. Below 768 this is off and the
   original wrap still stacks them.

   BLAST RADIUS, CHECKED BEFORE WRITING IT: .shr-s-people appears on ONE page
   of the site, About, once, with seven people. The placements also generalise,
   since anyone after the fourth is auto placed into the same six column
   rhythm. */
@media (min-width:768px){
  .shr-s-people{
    display:grid;
    grid-template-columns:repeat(24,1fr);
    align-items:start;
  }
  .shr-s-person{ grid-column:span 6; }
  .shr-s-person:nth-child(1){ grid-column:1 / span 6; }
  .shr-s-person:nth-child(2){ grid-column:10 / span 6; }
  .shr-s-person:nth-child(3){ grid-column:19 / span 6; }
  .shr-s-person:nth-child(4){ grid-column:1 / span 6; }
}

/* ==========================================================================
   SECTION 91. THE SERVICE PAGE INTRO SETS IN TWO COLUMNS AROUND ITS
   PHOTOGRAPH. 1.109.0
   ========================================================================== */

/* Kathleen, round 3, about every service page: "As I'm going through all the
   Service pages, I'm disliking the intro blurb format as one singular column.
   Can we change this to be either a more stretched format across the page, or
   two columns? Whatever design you think is best."

   The engine side of this, and why the photograph moves into the middle of
   the copy rather than beside it or above it, is written out in full at
   shr_sections_split_run() in inc/content-sections.php. The short of it:
   MEASURED at 1.108.0, all eight service pages ran 980 to 1,114px of copy
   beside a 258 to 318px photograph and carried 662 to 856px of empty column.
   A pair of readable columns needs the whole 1,256px row, so the picture
   cannot stay in it, and column-span:all is what lets the copy flow around
   it without leaving the multi column box.

   THE NUMBERS ARE NOT NEW. 72px gutter, the hairline rule at .2 alpha:
   .shr-e-prose--two has used both on the intro since 1.79.0 and
   .shr-e-lede--two since 1.87.1, so all three two column runs read as one
   device rather than three. A paragraph is never cut across the gutter, for
   the reason written at 1.87.2: a reader finishing a line on the left and
   finding the rest of the sentence at the top of the right column.

   WHY 1280 AND NOT 1024. The copy box is the viewport less 239px of chrome,
   capped at 1,256. MEASURED on the live page, 20px Montserrat runs 10.63px a
   character, so 45 characters needs 478px a column and a pair with the gutter
   needs 1,028px of copy, which is a 1,267px viewport. 1280 is that, rounded
   to a breakpoint the stylesheet already uses. MEASURED at the switch: 46
   characters at 1280, 50 at 1366, 53 at 1440, 56 at 1536 and above, against
   the 63 of the single column it replaces, all inside the 45 to 75 range.
   Below 1280 the copy is one column at the body measure, 68 characters, and
   the photograph runs the full width of the row between the halves.

   THE PLATE IS 12:5, which is not a guess either: it is the ratio
   .shr-s-band renders at on a desktop, MEASURED at 1,256 by 524. Fixing the
   ratio rather than reusing the band's 82vh keeps the picture the same shape
   whatever height the window is, and it means the plate and the band
   photograph that closes the same section are the same size on the page.
   object-position holds 45 per cent for the reason section 65 gives: that is
   where a building sits.

   BLAST RADIUS, MEASURED BEFORE WRITING THIS across all 248 addresses in the
   sitemap: thirteen stacks on thirteen pages take it, including all eight
   service page intros. About's "Supporting the Next Generation of Builders"
   has two paragraphs and does not, which leaves the section she approved at
   1.108.0 exactly as it is. No page gained a horizontal scrollbar at any of
   390, 600, 768, 900, 1024, 1180, 1280, 1366, 1440 or 1536. */

.shr-e-stack--two > .shr-e-stack__copy{ max-width:none; margin-inline:0; }
.shr-e-stack--two > .shr-e-stack__copy > p,
.shr-e-stack--two > .shr-e-stack__copy > h3,
.shr-e-stack--two > .shr-e-stack__copy > h4,
.shr-e-stack--two > .shr-e-stack__copy > ul,
.shr-e-stack--two > .shr-e-stack__copy > ol,
.shr-e-stack--two > .shr-e-stack__copy > blockquote,
.shr-e-stack--two > .shr-e-stack__copy > .shr-s-head{ max-width:var(--shr-measure-body); }
.shr-e-stack--two .shr-e-stack__media--span{ margin:36px 0; }

@media (min-width:1024px){
  /* 63.2 makes every .shr-e-stack a 7fr/5fr grid and pins its figure sticky
     inside the stretched column. This variant has one child and no second
     track, so both are undone here rather than guarded there. */
  .shr-e-section .shr-e-stack.shr-e-stack--two{ display:block; }
  .shr-e-section .shr-e-stack--two .shr-e-stack__media--span{ margin:48px 0 44px; }
  .shr-e-section .shr-e-stack--two .shr-e-stack__media--span > .shr-e-figure{
    position:static;
    top:auto;
    aspect-ratio:12/5;
    height:auto;
    max-height:none;
    margin:0;
  }
  .shr-e-section .shr-e-stack--two .shr-e-stack__media--span > .shr-e-figure > img{
    width:100%;
    height:100%;
    object-fit:cover;
    object-position:50% 45%;
  }
}

@media (min-width:1280px){
  .shr-e-section .shr-e-stack--two > .shr-e-stack__copy{
    columns:2;
    column-gap:72px;
    column-rule:1px solid rgba(90,107,120,.2);
  }
  .shr-e-section .shr-e-stack--two > .shr-e-stack__copy > p,
  .shr-e-section .shr-e-stack--two > .shr-e-stack__copy > h3,
  .shr-e-section .shr-e-stack--two > .shr-e-stack__copy > h4,
  .shr-e-section .shr-e-stack--two > .shr-e-stack__copy > ul,
  .shr-e-section .shr-e-stack--two > .shr-e-stack__copy > ol,
  .shr-e-section .shr-e-stack--two > .shr-e-stack__copy > blockquote{
    max-width:none;
    break-inside:avoid;
  }
  .shr-e-section .shr-e-stack--two > .shr-e-stack__copy > h3,
  .shr-e-section .shr-e-stack--two > .shr-e-stack__copy > h4{ break-after:avoid; }
  .shr-e-section .shr-e-stack--two > .shr-e-stack__copy > .shr-s-head{
    column-span:all;
    max-width:none;
  }
  .shr-e-section .shr-e-stack--two .shr-e-stack__media--span{ column-span:all; }
}

/* ==========================================================================
   SECTION 92. THE ROW A SERVICE PAGE CLOSES ON. 1.110.0
   ========================================================================== */

/* Quentin, 1 October, with a screenshot of Landscaping: "most of the service
   pages have two awkward images at the end of the page, make sure to add more
   and make it look nice instead of just adding two."

   .shr-s-strip prints the photographs the dealer did not place, in a three
   column grid. TWO of them therefore sit in the left two thirds with the right
   third empty, which is exactly the fault the four-tile rule in section 2 was
   written for: "Four photograph tiles in a three-up strip left one alone with
   827px of paper beside it." The same :has() shape fixes two.

   MEASURED at 1536 before this was written: Whole Home, Kitchens, Bathrooms,
   Custom Homes and Landscaping all close on two tiles at 403px wide with 426px
   of paper to the right of the second one.

   The edit is the other half. shr_sections_closing_plate() appends a chosen
   third photograph to each of those pages, so the row is a composed three-up
   rather than a pair of leftovers, and it gives Recreational Homes a closing
   row it never had. This rule stands whatever the count, so a page that ends
   on two for any reason still reads as a deliberate pair rather than a hole. */

@media (min-width:768px){
  .shr-s-strip:has(> :nth-child(2):last-child){
    grid-template-columns:repeat(2,minmax(0,1fr));
  }
}

/* ==========================================================================
   SECTION 93. THE CLOSING ROW IS ONE HEIGHT. 1.115.0
   ========================================================================== */

/* shr_sections_figure() gives every photograph the frame its own FILE wants,
   which is right everywhere else on the site and wrong in a tile row: the
   closing row on Custom Homes drew 296x197, 296x222, 296x167 and 296x112 side
   by side, because a 3:2, a 4:3 and two wide crops were sitting in one grid.
   MEASURED on the live page at 1.114.0.

   A tile is a thumbnail, not a plate, so it takes one frame and the picture
   is covered into it. 3:2 is the shape most of the library is shot at, so it
   crops the fewest of them. align-items is already start on .shr-s-strip, so
   without this the row simply hangs unevenly.

   Scoped to .shr-s-strip alone: bands, plates, splits and project cards are
   untouched, and a single leftover photograph does not render in a strip at
   all, so it keeps its own shape. */

.shr-s-strip > * > .shr-e-figure{
  aspect-ratio:3/2;
  max-height:none;
}
.shr-s-strip > * > .shr-e-figure > img{
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:50% 45%;
}

/* ==========================================================================
   SECTION 94. SIX TILES ARE TWO UP ON A TABLET. 1.115.0
   ========================================================================== */

/* .shr-s-strip goes three up at 768 and stays there. MEASURED on Recreational
   Homes at a 768 viewport after its closing row went from three tiles to six:
   each photograph draws 171x114. That is a contact sheet, not a closing row,
   and 768 is an iPad in portrait.

   Only a SIX tile strip gets this. Six divides by two, so three rows of two
   leave no hole. The four pages that close on three tiles keep the three up
   grid at every width, because two columns would orphan their third, which is
   the fault the 1.113.0 note above exists to prevent. The two tile strip is
   already handled by section 92.

   Above 1024 the inner is wide enough that three up draws 250px or better, so
   this lifts at that point and nothing changes on a laptop. */

@media (min-width:768px) and (max-width:1023px){
  .shr-s-strip:has(> :nth-child(6):last-child){
    grid-template-columns:repeat(2,minmax(0,1fr));
  }
}

/* ==========================================================================
   SECTION 95. THE QUOTE AND THE PORTRAIT, SIDE BY SIDE. 1.122.0
   ========================================================================== */

/* Kathleen, 1 October: "The photo of Mark next to his quote seems to have been
   removed." NEXT TO, not under it.

   1.121.0 got the portrait in and the layout wrong. It made the WHOLE prose
   box two columns, so the three body paragraphs that follow the pull quote
   were trapped in an 800px left column for the rest of the section with a
   dead 320px gutter beside them, and their own paragraph spacing then read as
   gappy because the measure had been cut. Quentin caught it on the live page.

   Only the first ROW is shared. The blockquote and the portrait sit side by
   side; every other child spans the full width underneath and keeps the
   measure it had before this rule existed. The section is a quote with a
   photograph beside it, then ordinary prose, which is what she asked for.

   Scoped by :has() to a prose box holding BOTH a blockquote and a companion,
   which on this site is the About opening and nothing else.

   align-items:start so the portrait hangs from the top of the quote rather
   than floating in the middle of a tall row. 320px keeps the 1200px file at
   0.27 of its own size, so it stays sharp. Below 860 the grid collapses and
   the portrait returns to the normal flow, capped so it does not fill a
   phone screen. */

/* 1.125.0. THE 540 PIXEL HOLE, AND WHAT WAS ACTUALLY CAUSING IT.
   MEASURED on the live page at 1536: the prose box was 1400 wide, the grid
   split it 880 and 320, and the blockquote inside that 880px column was
   drawing 396px wide and stopping. 484px of the column was empty, the 56px
   gap sat on top of it, and that is the 540px Quentin could see between the
   words and the man.
   The cap is section 39's `max-width:34ch` on the blockquote. ch is measured
   on the ELEMENT'S own font, which is 17.6px Montserrat, while the quotation
   inside it is set at 37.6px Playfair. So 34ch is 34 characters of the wrong
   typeface: it allows about 17 characters of the type it is actually holding,
   and the quote ran eight lines down a column twice its width.
   Inside this pairing the cap comes off and the column IS the measure.
   Section 40.2 already solved this exact layout for the portrait the page
   carries in its own content, so the geometry here is section 40.2's, not a
   second invention: 7fr and 4fr inside 1100px, a 72px gap, centred, and the
   two centred on each other. MEASURED with it applied: quotation 563 wide and
   391 tall, portrait 321 by 429, gap 72, and the pair inset by the same 150px
   on both sides. */

@media (min-width:860px){
  .shr-e-section .shr-e-prose:has(> blockquote):has(> .shr-e-companion){
    display:grid;
    grid-template-columns:minmax(0,7fr) minmax(0,4fr);
    column-gap:72px;
    align-items:center;
    max-width:min(1100px,100%);
    width:100%;
    margin-inline:auto;
  }
  .shr-e-section .shr-e-prose:has(> blockquote):has(> .shr-e-companion) > blockquote{
    grid-column:1;
    grid-row:1;
    margin:0;
    max-width:none;
  }
  .shr-e-section .shr-e-prose:has(> blockquote):has(> .shr-e-companion) > .shr-e-companion{
    grid-column:2;
    grid-row:1 / span 99;
    margin:0;
    align-self:center;
  }
  /* Everything after the quote returns to the full width of the section. */
  .shr-e-section .shr-e-prose:has(> blockquote):has(> .shr-e-companion)
    > :not(blockquote):not(.shr-e-companion){
    grid-column:1 / -1;
  }
}

@media (max-width:859px){
  .shr-e-prose:has(> blockquote) > .shr-e-companion{
    max-width:320px;
    margin-inline:auto;
  }
}

/* ==========================================================================
   SECTION 96. THE AWARDS PHOTOGRAPH. 1.122.0
   ========================================================================== */

/* shr_sections_section_photo() appends Mark's awards photograph inside An
   Award-Winning Team, under the award list. 4719 is 2560x1857, so left at the
   section measure it would draw a 1256px slab under a short list and dwarf
   the awards it is meant to illustrate.

   820px centred puts it at roughly two thirds of the band, which reads as a
   photograph belonging to the list above it rather than a new section. The
   file is drawn at 0.32 of its own width, so it stays sharp. */

.shr-s-section-photo{
  max-width:820px;
  margin-top:48px;
  margin-inline:auto;
}

@media (max-width:767px){
  .shr-s-section-photo{ margin-top:32px; }
}


/* ==========================================================================
   SECTION 97. THE ABOUT PAGE, 1 OCTOBER. 1.125.0
   ========================================================================== */

/* ---- 97.1 The blurb back under its own title ----------------------------
   Kathleen: "the blurb that went with the 'Thirty Years on the North Shore'
   section has been moved up. Can we revert this to what it was before."
   shr_sections_lift_opening_prose() takes the three paragraphs off the opening
   quotation and hands them to that section, which draws them between its title
   and its three figures. A reading measure, not the section measure: the
   figures beneath it are full width and the contrast is the point. */

.shr-e-inner > .shr-s-lifted{
  max-width:min(860px,100%);
  margin:0 0 56px;
}
@media (max-width:767px){
  .shr-e-inner > .shr-s-lifted{ margin-bottom:40px; }
}

/* ---- 97.2 The awards photograph, left, with the awards around it --------
   Quentin: "have the image on the left with the awards on the right and below
   the image at full width."
   The photograph is the first cell of the award grid and spans the first two
   rows of the left column. Grid auto placement does the rest: awards one and
   two take the right column beside it, and awards three and four land on row
   three across both columns, which is the full width under the picture. No
   float, no clearing, no nth-child arithmetic, and the award markup is
   untouched.
   The two column rule for this grid lives in the 1.49.1 block above and is
   written as "exactly four steps and no fifth child". A photograph IS a fifth
   child, so that rule stops matching the moment the picture arrives and the
   grid would collapse to one column. MEASURED, which is how it was caught.
   Both rules are restated here for the one case that carries a photograph. */

@media (min-width:768px){
  .shr-e-numbered:has(> .shr-s-award-photo){
    grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:64px;
  }
  .shr-e-numbered:has(> .shr-s-award-photo) .shr-e-step p{ max-width:46ch; }
  .shr-e-numbered > .shr-s-award-photo{
    grid-column:1;
    grid-row:1 / span 2;
    align-self:start;
    margin:0;
  }
}
/* The figure cap that section 40.2 had to fight is set with an important
   flag on every figure inside a section, so the grid cell answers it here. */
.shr-e-numbered > .shr-s-award-photo figure{
  max-width:none !important;
  margin:0;
}
@media (max-width:767px){
  .shr-e-numbered > .shr-s-award-photo{ margin-bottom:8px; }
}


/* ==========================================================================
   SECTION 98. THE BUILD CREDIT. 1.126.0
   ========================================================================== */

/* One line at the very bottom of every page, right aligned, under the
   copyright row rather than inside it. The row above is a space-between flex
   with exactly two children; a third would have moved "Serving North and West
   Vancouver" to the centre of a footer the client has already approved.

   Scoped with two classes because .shr-footer__base p already sets margin and
   colour at (0,1,1), and a single class would lose to it.

   .38 against the copyright line's .66. Quiet enough to read as part of the
   furniture, present enough to find. The link carries no underline until it
   is hovered or focused, so it does not pull the eye down the page. */

.shr-footer__base .shr-footer__built{
  max-width:1560px;
  margin:14px auto 0;
  text-align:right;
  color:rgba(251,250,247,.38);
}
.shr-footer__base .shr-footer__built a{
  color:inherit;
  text-decoration:none;
  border-bottom:1px solid transparent;
  transition:color .25s ease,border-color .25s ease;
}
.shr-footer__base .shr-footer__built a:hover,
.shr-footer__base .shr-footer__built a:focus-visible{
  color:rgba(251,250,247,.82);
  border-bottom-color:rgba(156,200,236,.5);
}
/* The row above goes left aligned on a phone, so this follows it rather than
   sitting alone against the right edge. */
@media (max-width:767px){
  .shr-footer__base .shr-footer__built{
    text-align:left;
    margin-top:12px;
  }
}
