/*
 * Site-specific CSS. Loaded last, after main.css.
 *
 * Rule: never edit assets/css/main.css or the vendor plugin CSS. Brand tokens
 * belong in assets/scss/abstracts/_variables.scss (recompile with `npm run css`);
 * one-off corrections and anything the theme does not expose belong here.
 * Bump the ?v= querystring in the <head> when you change this file.
 */

/* Brand tokens. Override the template palette without touching the SCSS build. */
:root {
  /* --color-primary:     #209D50;  Weka Solar accent, set in _variables.scss */
  /* --color-primary-two: #FCCA03; */
  /* --color-secondary:   #310875; */
}

/* ------------------------------------------------------------------ *
 * Weka Solar logo
 *
 * Only a black wordmark exists, so it is inverted to white for the one
 * place it sits on a dark surface: the transparent header over the hero
 * image (.logo1). The sticky header (.logo2), the mobile menu panel and
 * the footer are all light, so those keep the artwork as supplied. The
 * footer looks dark but its ::before paints #f3f3f3.
 *
 * Replace this with a real white SVG from the client when one exists,
 * and delete the filter. brightness(0) invert(1) flattens the mark to
 * pure white, which loses any future two-tone treatment.
 * ------------------------------------------------------------------ */
.header-logo .logo1 img {
  filter: brightness(0) invert(1);
}

/* The wordmark is 1999x544, much wider than the square-ish SVGs it
   replaced, so cap it by height and let the width follow. */
.header-logo img,
.xb-logo-mobile img,
.xb-item--logo img {
  height: 84px;
  width: auto;
  max-width: none;
}
/* The header row has to grow with it or the mark gets clipped by the
   sticky bar. */
.xb-header .header__wrap,
.header-logo {
  min-height: 96px;
}
@media (max-width: 1199px) {
  .header-logo img,
  .xb-logo-mobile img,
  .xb-item--logo img {
    height: 64px;
  }
  .xb-header .header__wrap,
  .header-logo {
    min-height: 76px;
  }
}
@media (max-width: 575px) {
  .header-logo img,
  .xb-logo-mobile img,
  .xb-item--logo img {
    height: 52px;
  }
  .xb-header .header__wrap,
  .header-logo {
    min-height: 64px;
  }
}

/* ------------------------------------------------------------------ *
 * Real photography slots
 *
 * The client's photos are phone shots, mostly 3:4 portrait, dropped into
 * slots the template filled with landscape stock. Only .xb-work-item
 * shipped with object-fit, so the ratio is pinned here and the browser
 * crops rather than letting a tall image stretch the layout.
 *
 * Ratios match the stock images they replaced, so surrounding spacing is
 * unchanged. object-position favours the upper part of the frame, which
 * is where the roof and array sit in every one of these photos.
 * ------------------------------------------------------------------ */
.project-single-item .image img {
  aspect-ratio: 410 / 364;
  object-fit: cover;
  object-position: 50% 40%;
  width: 100%;
  height: auto;
}
.xb-about-img img {
  aspect-ratio: 1040 / 1160;
  object-fit: cover;
  object-position: 50% 45%;
  width: 100%;
  height: auto;
}
.about-mission-item-img img {
  aspect-ratio: 580 / 612;
  object-fit: cover;
  object-position: 50% 40%;
  width: 100%;
  height: auto;
}
.ab-highly-img img {
  aspect-ratio: 415 / 538;
  object-fit: cover;
  object-position: 50% 30%; /* portrait subject: bias to the head */
  width: 100%;
  height: auto;
}

/* Honeypot. Must stay visually hidden but focusable-free for bots to fall in. */
.hp-field {
  position: absolute !important;
  left: -9999px !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Inline form feedback rendered by assets/js/site-extras.js */
.form-status {
  margin: 18px 0 0;
  font-size: 15px;
  line-height: 1.5;
  min-height: 1em;
}
.form-status.is-error {
  color: #d64545;
}
.form-status.is-success {
  color: #2f9e58;
}

.cf-turnstile {
  margin-top: 20px;
}

/* The theme ships submit buttons outside the <form>. Where that has been
   corrected the button keeps its original spacing. */
form .contact-btn {
  margin-top: 35px;
}

/* The theme sets text-transform:capitalize on body paragraphs. That reads fine
   on the four-word filler it shipped with, and badly on real sentences:
   "We Are A Local, All In-House Solar Company Based On The Kapiti Coast".
   Headings keep their treatment, body copy does not. */
.wcu-content,
.xb-content,
.xb-about-content p,
.xb-process-image .xb-holder p,
.xb-item--content,
.xb-item--address,
.acc_body .content,
.xb-faq-left .xb-item--content {
  text-transform: none;
}

/* ------------------------------------------------------------------ *
 * Scrim on photographic sections
 *
 * The template shipped flat grey placeholder images (75 of its 86), so
 * every section designed for white-text-on-a-dark-photo was rendering
 * white text on rgb(170,170,170). Measured 2.3:1 for the hero heading
 * and 1.51:1 for its green highlight span, against a 3:1 requirement.
 *
 * Those sections now carry real client photography, and this scrim
 * guarantees the text stays readable over any of them. The tint matches
 * what Weka use on their own site, rgba(29,35,28,...).
 *
 * The theme ships an unused [data-overlay] system, but it has no
 * z-index handling so its ::before paints over the content. This does
 * the same job with the stacking fixed.
 *
 * Excluded: .contact-overlay and .about-contact-form, which already
 * paint their own ::before and would end up double-darkened.
 * ------------------------------------------------------------------ */
.bg_img:not(.contact-overlay):not(.about-contact-form) {
  position: relative;
  isolation: isolate;
}
.bg_img:not(.contact-overlay):not(.about-contact-form)::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(29, 35, 28, 0.75);
  pointer-events: none;
}

/* ------------------------------------------------------------------ *
 * Brand green as TEXT
 *
 * #209D50 is mid-luminance, which makes it a good fill behind white
 * text but a poor text colour at both ends:
 *   on white            3.5:1  (needs 4.5:1 for body text)
 *   on the scrimmed hero 3.1:1  (needs 3:1, ie. no headroom)
 *
 * So the fill stays #209D50 and text gets two tuned variants. Both are
 * the same hue, just moved in lightness.
 * ------------------------------------------------------------------ */
:root {
  --brand-green-on-light: #17703A; /* ~6:1 on white */
  --brand-green-on-dark:  #3FCB74; /* ~5:1 over the scrim */
}

/* Green text sitting on white or light surfaces */
.sec-title .xb-title span,
.footer-style-two .xb-footer_widget .xb-list li a:hover,
.btn-video:hover,
.pagination_wrap ul li a,
.header-style-two .header__wrap .main-menu__wrap .main-menu > ul > li:hover > a,
.header-style-two .header__wrap .main-menu__wrap .main-menu > ul > li.active > a,
.header-style-two .header-contact .number,
.main-menu ul li .submenu li:hover > a,
.main-menu ul li .submenu li.active > a,
.xb-item-item .xb-item--number,
.xb-work-item .xb-item--read-btn:hover,
.xb-about-content p a,
.process-content a,
.xb-testimonial-item .xb-item--author,
.sec-title--two .sub_title {
  color: var(--brand-green-on-light);
}

/* ...and the same green where it sits on a scrimmed photo instead */
.bg_img .sec-title .xb-title span,
.bg_img .xb-hero_content .xb-title span,
.hero-style-one .xb-hero_content .xb-title span,
.bg_img .sec-title--two .sub_title {
  color: var(--brand-green-on-dark);
}

/* More capitalize cleanup. Same reasoning as the block above: these hold
   real sentences, not the template's short filler. The FAQ one matters
   most, it was rendering "Do Solar Panels Work During Cloudy Days Or At
   Night?" on every page that carries the accordion. */
.sec-title p,
.about-mission-item .sec-title p,
.ab-highly-left-content .about-hoder p,
.acc-btn,
.xb-item--day {
  text-transform: none;
}

/* The theme hardcodes an underscore as the breadcrumb divider, so every
   inner page reads "Home_About Us". */
.breadcrumb-item + .breadcrumb-item {
  --bs-breadcrumb-divider: "/";
}
.breadcrumb-item + .breadcrumb-item {
  margin-left: 0;          /* main.css pulls the slash back onto the word */
}
.breadcrumb-item + .breadcrumb-item::before {
  padding-right: 8px;
  padding-left: 8px;
  opacity: 0.7;
}

/* The stat numbers sit on the .bg-gradient band, not on white, so the
   light-surface green would render dark-on-green. White matches the
   labels beside them and clears AA at both sizes on the deepened
   gradient (about 5:1 at its lightest stop). */
.bg-gradient .xb-item-item .xb-item--number,
.bg-gradient .xb-item-item .xb-item--number .xbo,
.bg-gradient .xb-item-item .xb-item--number .suffix {
  color: var(--color-white);
}

/* ------------------------------------------------------------------ *
 * Green text on DARK surfaces
 *
 * --brand-green-on-light is tuned for white backgrounds. Several of the
 * selectors that use it also appear inside dark panels (.bg-gradient,
 * the scrimmed photo sections, and the solid green bands), where a dark
 * green renders almost invisibly. The phone link in the about copy was
 * the worst case: #17703A on the green gradient.
 *
 * White wins here over the light-green variant, because the gradient's
 * lighter stop only gives the light green about 2.4:1, while white holds
 * roughly 5:1 across the whole ramp. Links keep an underline so they are
 * still identifiable without relying on colour.
 * ------------------------------------------------------------------ */
.bg-gradient a,
.bg-gradient .xb-about-content p a,
.bg-gradient .process-content a,
.bg-gradient .xb-item--number,
.bg-gradient .sec-title .xb-title span,
.bg_img .xb-about-content p a,
.bg_img .process-content a {
  color: var(--color-white);
}
.bg-gradient .xb-about-content p a,
.bg_img .xb-about-content p a,
.bg-gradient .process-content a,
.bg_img .process-content a {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* .sec-title .title span is #24572f, a dark green. Fine on the light
   section fills (#FCCA03, #dbfbff) and on white, but it disappears on
   every dark fill. "Why Choose Weka Solar?" measured 2.42:1 with the
   span on the brand green. White on those, which pairs with the
   near-black heading beside it as a deliberate two-tone. */
[data-bg-color="#209D50"] .sec-title .title span,
[data-bg-color="#000"] .sec-title .title span,
[data-bg-color="#0d0d0d"] .sec-title .title span,
[data-bg-color="#310875"] .sec-title .title span,
[data-bg-color="#0a55c7"] .sec-title .title span,
.bg-gradient .sec-title .title span,
.bg_img .sec-title .title span {
  color: var(--color-white);
}

/* --- contrast sweep, round two ------------------------------------- */

/* .xb-wcu paints the brand green itself rather than via data-bg-color,
   so the earlier attribute-scoped rule missed it. */
.xb-wcu .sec-title .title span {
  color: var(--color-white);
}

/* .sec-title--two .sub_title uses the light-surface green, but the
   section it sits in is filled purple on commercial-solar (2.4:1). */
[data-bg-color="#310875"] .sub_title,
[data-bg-color="#0d0d0d"] .sub_title,
[data-bg-color="#000"] .sub_title,
.bg-gradient .sub_title {
  color: var(--color-white);
}

/* The contact block on privacy and terms renders its number and email
   white on a white card. */
.xb-contact-information-item .xb-item--number,
.xb-contact-information-item .xb-item--holder p {
  color: #0d0d0d;
}

/* The feature cards put a white 40px heading over their image, with a
   rgba(255,255,255,0.3) wash on top. That was legible over the template's
   dark demo photos but not over anything light, and measured 1:1 against
   the grey placeholder. Real photos now sit behind them, and the wash is
   inverted to a dark scrim so the heading holds up over any of them. */
.xb-feature-item::after {
  background: rgba(29, 35, 28, 0.55) !important;
}
.xb-feature-item .xb-item--img img {
  aspect-ratio: 645 / 605;
  object-fit: cover;
  object-position: 50% 45%;
  width: 100%;
  height: auto;
}

/* --- contrast sweep, round three ----------------------------------- */

/* "Play Video" is white text sitting directly on the white page. */
.play-video span,
.play-video a {
  color: #0d0d0d;
}

/* The closing CTA heading is black, which worked over the template's
   dark demo photo but not over the scrim now on .cta.bg_img. */
.cta.bg_img .cta-content .title,
.cta.bg_img .cta-content .title span {
  color: var(--color-white);
}

/* .clr-green is a light green used as a section eyebrow on white. */
.clr-green {
  color: var(--brand-green-on-light) !important;
}

/* ------------------------------------------------------------------ *
 * Contact info block
 *
 * .contact-mail is 30px with letter-spacing: 0.23em, which the template
 * used for a short URL ("www.solargen.com"). An email address is far
 * longer, so it blew across the column and broke mid-word. Sized down,
 * tracking removed, and allowed to wrap at sensible points.
 * ------------------------------------------------------------------ */
.contact-info_widget .contact-mail,
a.contact-mail {
  font-size: 20px;
  letter-spacing: 0;
  text-transform: none;
  word-break: break-word;
  overflow-wrap: anywhere;
  line-height: 1.4;
  text-decoration: underline;
  text-underline-offset: 3px;
}
@media (max-width: 991px) {
  .contact-info_widget .contact-mail,
  a.contact-mail {
    font-size: 18px;
  }
}

/* The block's headings and body are capitalised by the theme, which
   turns an address and an email into Title Case. */
.contact-info_widget .xb-location,
.contact-info_widget .contact-mail {
  text-transform: none;
}

/* The contact info list capitalises its items, which turned the email
   into "Office@Wekasolar.Co.Nz". Addresses and emails are not titles. */
.item-contact_info ul li,
.item-contact_info ul li a,
.contact-info_widget .xb-location {
  text-transform: none;
}
.item-contact_info ul li a {
  color: inherit;
  overflow-wrap: anywhere;
}
.item-contact_info ul li a:hover {
  text-decoration: underline;
}

/* The form intro is a sentence, not a title. */
.form-heading .content,
.xb-main-contact .form-heading p {
  text-transform: none;
}

/* ------------------------------------------------------------------ *
 * Hero supporting paragraph
 *
 * hero-style-one shipped with no paragraph between the h1 and the
 * buttons, so this needs its own type scale. Measure is capped so the
 * line length stays readable over the full-bleed hero photo.
 * ------------------------------------------------------------------ */
.xb-hero_content .hero-desc {
  margin: 26px 0 0;
  max-width: 620px;
  color: var(--color-white);
  font-size: clamp(17px, 1.25vw, 20px);
  line-height: 1.6;
  text-transform: none;
  font-weight: 400;
}
@media (max-width: 991px) {
  .xb-hero_content .hero-desc {
    margin-top: 20px;
    max-width: 100%;
  }
}

/* ------------------------------------------------------------------ *
 * Commercial page: green finance cards
 *
 * New block, no theme class fits. Every major NZ bank runs a lending
 * programme for emissions-reducing projects and Weka's own page names
 * five of them. None of the five states a rate, so none is given here.
 * ------------------------------------------------------------------ */
.xb-lender-item {
  height: 100%;
  padding: 30px 28px;
  border: 1px solid rgba(13, 13, 13, 0.12);
  border-radius: 14px;
  background: #fff;
  transition: border-color .3s, transform .3s;
}
.xb-lender-item:hover {
  border-color: var(--color-primary);
  transform: translateY(-3px);
}
.xb-lender-item .xb-item--title {
  font-size: 24px;
  margin-bottom: 12px;
}
.xb-lender-item .xb-item--content {
  font-size: 16px;
  line-height: 1.6;
  text-transform: none;
  margin-bottom: 16px;
  color: #444a4b;
}
.xb-lender-item a {
  font-weight: 600;
  font-size: 15px;
  color: var(--brand-green-on-light);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ------------------------------------------------------------------ *
 * FAQ accordion on a LIGHT section
 *
 * The theme colours .acc-btn and .acc_body .content white, because every
 * FAQ it shipped sat on a dark fill. The commercial page's FAQ sits on
 * white, so every question and answer was rendering white on white at
 * 1:1, completely invisible.
 *
 * Scoped by the absence of a data-bg-color fill: the farm page's FAQ is
 * on #000 and keeps the white text.
 * ------------------------------------------------------------------ */
.faq:not([data-bg-color]) .acc-btn,
.faq:not([data-bg-color]) .acc_body .content,
.faq:not([data-bg-color]) .xb-faq-left .xb-item--content {
  color: #0d0d0d;
}
.faq:not([data-bg-color]) .acc-btn .arrow {
  color: #0d0d0d;
}

/* ------------------------------------------------------------------ *
 * Light-section text fixes
 *
 * The theme assumes .xb-content and .sub_title sit on a filled section,
 * so it colours them white. The modelling, finance and FAQ blocks added
 * to the commercial page sit on plain white, where that renders 1:1.
 *
 * Keyed off whether the section carries a data-bg-color fill, so the
 * filled sections (green, deep green, black) keep their white text.
 * ------------------------------------------------------------------ */
section:not([data-bg-color]) .xb-content,
section:not([data-bg-color]) .sec-title p.xb-content {
  color: #444a4b;
}

/* The eyebrow on a deep-green fill. Previously scoped to the template's
   purple, which no longer exists. */
[data-bg-color="#17532F"] .sub_title,
[data-bg-color="#17532F"] .sec-title .title span,
[data-bg-color="#17532F"] .xb-content {
  color: var(--color-white);
}
section:not([data-bg-color]) .sub_title {
  color: var(--brand-green-on-light);
}

/* The two eyebrow pills on the farm page are labels, not buttons. The
   template painted them with the secondary fill and they lost contrast
   when that token changed. Made explicit rather than left to inherit. */
.thm-btn.power-btn--balck,
.power-btn--balck {
  color: var(--color-white) !important;
}
.power-btn--balck::before {
  /* Was #0d0d0d. Pure black is not in the palette, and these sit on
     light sections where a black pill reads as a foreign element. */
  background: #17532F !important;
  border-color: #17532F !important;
}

/* ------------------------------------------------------------------ *
 * Footer text colour, stated rather than inherited
 *
 * .footer-style-one paints #f3f3f3 via ::before and relies on the body
 * default for its text. That default differs per page: .residential_solar
 * is dark, .commercial_solar and .power-solution are white. So the same
 * footer markup rendered dark on the homepage and white-on-white on the
 * two service pages once they shared it.
 *
 * Setting it here makes the footer self-contained, so it can be dropped
 * on any page regardless of that page's body class.
 * ------------------------------------------------------------------ */
.footer-style-one,
.footer-style-one .xb-item--content,
.footer-style-one .xb-item--address,
.footer-style-one .xb-item--day,
.footer-style-one .xb-widget-title,
.footer-style-one .xb-list li a,
.footer-style-one .xb-item--contact,
.footer-style-one .xb-item--contact a,
.footer-style-one .xb-footer-bottom p,
.footer-style-one .xb-footer-bottom a {
  color: #0d0d0d;
}
.footer-style-one .xb-list li a:hover,
.footer-style-one .xb-footer-bottom a:hover {
  color: var(--brand-green-on-light);
}

/* ------------------------------------------------------------------ *
 * Real photography, round two
 *
 * Thirty-one slots were still holding the template's flat grey filler.
 * They were invisible to the content audit because the "350X260" is
 * painted inside the JPEG, not written in the markup; they were found by
 * bytes-per-pixel instead (flat grey lands under 0.05 B/px, a real photo
 * sits at 0.06 and up).
 *
 * Same treatment as the first round. Every ratio below is the ratio of
 * the placeholder it replaced, so section heights and the spacing either
 * side of them are unchanged. Weka's photos are phone shots in 3:4
 * portrait, so without a pinned ratio each one would run to three times
 * the height of its slot. object-position is biased up the frame, which
 * is where the roof and the array sit in all seven.
 * ------------------------------------------------------------------ */
.xb-process-image .item-image img {           /* was 630x460 */
  aspect-ratio: 630 / 460;
  object-fit: cover;
  object-position: 50% 35%;
  width: 100%;
  height: auto;
}
.service .acc_body .content img {             /* was 1290x450, a wide band */
  aspect-ratio: 1290 / 450;
  object-fit: cover;
  object-position: 50% 40%;
  width: 100%;
  height: auto;
}
.xb-work-item .xb-item--img img {             /* was 615x546 */
  aspect-ratio: 615 / 546;
  object-fit: cover;
  object-position: 50% 40%;
  width: 100%;
  height: auto;
}
.about-details-img img {                      /* was 1290x582 */
  aspect-ratio: 1290 / 582;
  object-fit: cover;
  object-position: 50% 45%;
  width: 100%;
  height: auto;
}
.service-details-img img {                    /* was 1290x550 */
  aspect-ratio: 1290 / 550;
  object-fit: cover;
  object-position: 50% 45%;
  width: 100%;
  height: auto;
}
.ser-benefit-item-img .img img {              /* was 395x240 */
  aspect-ratio: 395 / 240;
  object-fit: cover;
  object-position: 50% 40%;
  width: 100%;
  height: auto;
}
.about-right-content .xb-img img {            /* was 630x477 */
  aspect-ratio: 630 / 477;
  object-fit: cover;
  object-position: 50% 40%;
  width: 100%;
  height: auto;
}
.overview-item .xb-img img {                  /* was 300x271 */
  aspect-ratio: 300 / 271;
  object-fit: cover;
  object-position: 50% 40%;
  width: 100%;
  height: auto;
}
.overview-item--big .xb-img img {             /* was 630x483 */
  aspect-ratio: 630 / 483;
  object-fit: cover;
  object-position: 50% 40%;
  width: 100%;
  height: auto;
}
/* The infographic pair is bottom-aligned and the two slots are different
   heights by design, so they are pinned separately rather than together. */
.infographic-left-content .xb-img:nth-of-type(1) img {   /* was 232x280 */
  aspect-ratio: 232 / 280;
  object-fit: cover;
  object-position: 50% 35%;
  width: 100%;
  height: auto;
}
.infographic-left-content .xb-img:nth-of-type(2) img {   /* was 375x442 */
  aspect-ratio: 375 / 442;
  object-fit: cover;
  object-position: 50% 35%;
  width: 100%;
  height: auto;
}
.project-item .xb-item--img img {             /* was 630x509 */
  aspect-ratio: 630 / 509;
  object-fit: cover;
  object-position: 50% 40%;
  width: 100%;
  height: auto;
}
.faq-left-content img {                       /* was 520x619 */
  aspect-ratio: 520 / 619;
  object-fit: cover;
  object-position: 50% 35%;
  width: 100%;
  height: auto;
}
.project-details-banner img {                 /* was 1290x530 */
  aspect-ratio: 1290 / 530;
  object-fit: cover;
  object-position: 50% 45%;
  width: 100%;
  height: auto;
}
/* The template leaves this anchor inline, so it wrapped a block image with a
   22px line box: the photo was not clickable, only the caption under it. The
   projects grid already solves this the same way at .project-single-item
   .image, so "Other projects" now matches it. */
/* Each tile is one anchor around the photo, the title and the caption, so
   every pixel of the card navigates. It also has to look like a link:
   with no hover state at all, a bare photo above a black heading reads as
   decoration rather than something you can click. */
/* main.css paints a white gloss sweep across the card on hover:
   .project-details-img::after, 200% wide, growing from 0% to 250% height at
   z-index 1. It belongs to the wrapper div, not to the link inside it, so
   the moment it covers the card the hover moves off the anchor. The link
   styling flickers on and off, and a click that lands on the sweep hits the
   div and does nothing. That is the bug Jared kept hitting, and the white
   flash he saw is the same element. It is decorative, so it goes.

   It stays invisible to hit testing in any case, because a decoration that
   can swallow a click is the fault, not just this instance of it. */
.project-details-img::after {
  content: none;
  pointer-events: none;
}

.project-details-img__link {
  display: block;
  color: inherit;
  text-decoration: none;
}
.project-details-img__media {
  display: block;
  overflow: hidden;              /* holds the zoom inside the frame */
}
.project-details-img__link img { transition: transform 0.4s ease; }
.project-details-img__link:hover img,
.project-details-img__link:focus-visible img { transform: scale(1.04); }
.project-details-img__link:hover .project-details-img__cap,
.project-details-img__link:focus-visible .project-details-img__cap {
  color: var(--brand-green-on-light);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.project-details-img__link:focus-visible {
  outline: 2px solid var(--brand-green-on-light);
  outline-offset: 4px;
}
@media (prefers-reduced-motion: reduce) {
  .project-details-img__link img { transition: none; }
  .project-details-img__link:hover img { transform: none; }
}
.project-details-img img {                    /* was 410x364 */
  aspect-ratio: 410 / 364;
  object-fit: cover;
  object-position: 50% 40%;
  width: 100%;
  height: auto;
}

/* ------------------------------------------------------------------ *
 * Crop framing, per photo per slot
 *
 * object-position is not a point of interest, it is a scroll offset into
 * whatever overflow object-fit: cover leaves behind. How far a given
 * percentage actually moves the image depends on how much overflow there
 * is, which depends on the slot's ratio. The same photo therefore needs a
 * different percentage in the 2.87:1 accordion band than in a 1.13:1 card,
 * and one value per photo is wrong in both.
 *
 *   vis   = source ratio / slot ratio      how much of the frame is shown
 *   top   = subject centre - vis / 2       where that strip should start
 *   pos-y = top / (1 - vis)                the percentage that puts it there
 *
 * The subject centre of each photo was read off the file. The earlier note
 * in this stylesheet said to bias up the frame; that holds only for the two
 * shots taken looking down. In the other five the array sits in the lower
 * half and the top 40 to 55 per cent is empty sky, so a high-40s value was
 * cropping to cloud. Values here are generated, not guessed; the comment on
 * each says what ends up on screen.
 * ------------------------------------------------------------------ */
/* .xb-process-image .item-image img   slot 1.37:1 */
.xb-process-image .item-image img[src$="bush-hillside-array.jpg"] {
  object-position: 50% 61%;   /* shows 55% of the frame, centred on 55% */
}
.xb-process-image .item-image img[src$="coastal-home-dusk.jpg"] {
  object-position: 50% 86%;   /* shows 55% of the frame, centred on 66% */
}
.xb-process-image .item-image img[src$="founder-portrait.jpg"] {
  object-position: 50% 94%;   /* shows 55% of the frame, centred on 70% */
}
.xb-process-image .item-image img[src$="installer-placing-panel.jpg"] {
  object-position: 50% 50%;   /* shows 55% of the frame, centred on 50% */
}
.xb-process-image .item-image img[src$="installers-on-roof.jpg"] {
  object-position: 50% 100%;   /* shows 97% of the frame, centred on 60% */
}

/* .service .acc_body .content img   slot 2.87:1 */
.service .acc_body .content img[src$="coastal-home-dusk.jpg"] {
  object-position: 50% 72%;   /* shows 26% of the frame, centred on 66% */
}
.service .acc_body .content img[src$="installers-on-roof.jpg"] {
  object-position: 50% 69%;   /* shows 47% of the frame, centred on 60% */
}
.service .acc_body .content img[src$="rural-array-valley.jpg"] {
  object-position: 50% 66%;   /* shows 26% of the frame, centred on 62% */
}
.service .acc_body .content img[src$="rural-roof-array.jpg"] {
  object-position: 50% 72%;   /* shows 26% of the frame, centred on 66% */
}

/* .xb-work-item .xb-item--img img   slot 1.13:1 */
.xb-work-item .xb-item--img img[src$="bush-hillside-array.jpg"] {
  object-position: 50% 65%;   /* shows 67% of the frame, centred on 55% */
}
.xb-work-item .xb-item--img img[src$="coastal-home-dusk.jpg"] {
  object-position: 50% 98%;   /* shows 67% of the frame, centred on 66% */
}
.xb-work-item .xb-item--img img[src$="installer-placing-panel.jpg"] {
  object-position: 50% 50%;   /* shows 67% of the frame, centred on 50% */
}
/*   installers-on-roof.jpg         full height shown, no vertical crop */
.xb-work-item .xb-item--img img[src$="rural-array-valley.jpg"] {
  object-position: 50% 86%;   /* shows 67% of the frame, centred on 62% */
}

/* .about-details-img img   slot 2.22:1 */
.about-details-img img[src$="installers-on-roof.jpg"] {
  object-position: 50% 75%;   /* shows 60% of the frame, centred on 60% */
}

/* .service-details-img img   slot 2.35:1 */
.service-details-img img[src$="coastal-home-dusk.jpg"] {
  object-position: 50% 74%;   /* shows 32% of the frame, centred on 66% */
}

/* .ser-benefit-item-img .img img   slot 1.65:1 */
.ser-benefit-item-img .img img[src$="bush-hillside-array.jpg"] {
  object-position: 50% 59%;   /* shows 46% of the frame, centred on 55% */
}
.ser-benefit-item-img .img img[src$="installer-placing-panel.jpg"] {
  object-position: 50% 50%;   /* shows 46% of the frame, centred on 50% */
}

/* .about-right-content .xb-img img   slot 1.32:1 */
/*   installers-on-roof.jpg         full height shown, no vertical crop */

/* .overview-item .xb-img img   slot 1.11:1 */
.overview-item .xb-img img[src$="installer-placing-panel.jpg"] {
  object-position: 50% 50%;   /* shows 68% of the frame, centred on 50% */
}

/* .overview-item--big .xb-img img   slot 1.30:1 */
.overview-item--big .xb-img img[src$="rural-roof-array.jpg"] {
  object-position: 50% 88%;   /* shows 57% of the frame, centred on 66% */
}

/* .infographic-left-content .xb-img:nth-of-type(1) img   slot 0.83:1 */
.infographic-left-content .xb-img:nth-of-type(1) img[src$="coastal-home-dusk.jpg"] {
  object-position: 50% 100%;   /* shows 91% of the frame, centred on 66% */
}

/* .infographic-left-content .xb-img:nth-of-type(2) img   slot 0.85:1 */
.infographic-left-content .xb-img:nth-of-type(2) img[src$="bush-hillside-array.jpg"] {
  object-position: 50% 93%;   /* shows 88% of the frame, centred on 55% */
}

/* .project-item .xb-item--img img   slot 1.24:1 */
.project-item .xb-item--img img[src$="bush-hillside-array.jpg"] {
  object-position: 50% 63%;   /* shows 61% of the frame, centred on 55% */
}
.project-item .xb-item--img img[src$="rural-array-valley.jpg"] {
  object-position: 50% 80%;   /* shows 61% of the frame, centred on 62% */
}
.project-item .xb-item--img img[src$="rural-roof-array.jpg"] {
  object-position: 50% 91%;   /* shows 61% of the frame, centred on 66% */
}

/* .faq-left-content img   slot 0.84:1 */
/*   installers-on-roof.jpg         full height shown, no vertical crop */

/* .project-details-banner img   slot 2.43:1 */
.project-details-banner img[src$="coastal-home-dusk.jpg"] {
  object-position: 50% 73%;   /* shows 31% of the frame, centred on 66% */
}

/* .project-details-img img   slot 1.13:1 */
.project-details-img img[src$="bush-hillside-array.jpg"] {
  object-position: 50% 65%;   /* shows 67% of the frame, centred on 55% */
}
.project-details-img img[src$="installer-placing-panel.jpg"] {
  object-position: 50% 50%;   /* shows 67% of the frame, centred on 50% */
}
.project-details-img img[src$="rural-roof-array.jpg"] {
  object-position: 50% 98%;   /* shows 67% of the frame, centred on 66% */
}

/* ------------------------------------------------------------------ *
 * Hero CTA on small screens
 *
 * "Get a free system assessment" is 28 characters against the 11 of the
 * "Get a quote" the template was measured with. At 20px bold uppercase
 * with 30px of side padding it needs 398px, and a 375px phone offers 351,
 * so it wrapped to two lines and stood 76px tall beside a 60px sibling.
 *
 * Both hero buttons go full width and share a height below 576px, so the
 * pair reads as a deliberate stack, and the type comes down enough that
 * the label holds one line at 375px. Narrower than about 330px it wraps
 * again, but by then both buttons are the same width and it still looks
 * intentional rather than broken.
 * ------------------------------------------------------------------ */
@media (max-width: 575px) {
  .hero-style-one .xb-hero_content .hero-btn {
    gap: 14px;
  }
  .hero-style-one .xb-hero_content .hero-btn .thm-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 58px;
    padding: 16px 18px;
    /* 17px on a 375px phone, easing down so the label still holds one line
       on a 320px one, where it needs to lose about 47px of its own width. */
    font-size: clamp(15px, 4.6vw, 17px);
    line-height: 1.25;
    text-align: center;
  }
}

/* ================================================================== *
 * Blueprint step 1 and homepage (content/page-blueprints.md)
 * ================================================================== */

/* --- Trust strip ---------------------------------------------------- *
 * Sits inside dark heroes, directly under the CTAs, so a visitor from a
 * high-intent search sees the credentials without scrolling. Inside the
 * hero rather than after it, because the homepage's next card overlaps
 * the hero's bottom edge. */
.trust-strip {
  list-style: none;
  margin: 34px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
}
.trust-strip li {
  position: relative;
  padding-left: 26px;
  color: #ffffff;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.4;
}
.trust-strip li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 3px;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: var(--color-primary)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.4l2.9 2.8 6-6.4' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    center / 11px no-repeat;
}
.breadcrumb .trust-strip {
  justify-content: center;
  margin-top: 26px;
}
@media (max-width: 575px) {
  .trust-strip { gap: 8px 18px; margin-top: 26px; }
  .trust-strip li { font-size: 14px; flex: 1 1 calc(50% - 18px); }
}

/* --- Counters: were H2s, now divs ---------------------------------- *
 * Keeps the look the H2 base styles gave them. */
.xb-item-item div.xb-item--number {
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: 0;
}

/* --- Buttons: long CTA labels wrap cleanly on phones --------------- */
@media (max-width: 575px) {
  .thm-btn {
    max-width: 100%;
    white-space: normal;
    text-align: center;
    line-height: 1.3;
  }
}

/* --- How it works (homepage summary) ------------------------------- */
.hiw-intro {
  margin: 22px 0 26px;
  font-size: 18px;
  line-height: 1.6;
  color: #3d4540;
}
.hiw-link {
  font-weight: 700;
  color: var(--brand-green-on-light);
  text-decoration: underline;
  text-underline-offset: 4px;
}
.hiw-link:hover { color: var(--color-heading); }
.hiw-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 16px;
}
.hiw-steps li {
  display: flex;
  gap: 20px;
  align-items: flex-start;
  padding: 24px 26px;
  background: #ffffff;
  border-left: 4px solid var(--color-primary);
}
.hiw-num {
  flex: 0 0 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-primary);
  color: #ffffff;
  font-family: var(--font-heading);
  font-size: 20px;
  font-weight: 700;
}
.hiw-steps h3 {
  font-size: 21px;
  font-weight: 700;
  margin: 2px 0 6px;
  color: var(--color-heading);
}
.hiw-steps p {
  margin: 0;
  color: #3d4540;
  line-height: 1.6;
}

/* --- Segment cards ---------------------------------------------------- */
.segments-lead {
  max-width: 640px;
  margin: 18px auto 0;
  font-size: 18px;
  line-height: 1.6;
  color: #3d4540;
}
.segment-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #ffffff;
  color: inherit;
  box-shadow: 0 1px 2px rgba(13, 13, 13, 0.06);
  transition: box-shadow 0.25s, transform 0.25s;
}
.segment-card:hover {
  box-shadow: 0 14px 34px rgba(13, 13, 13, 0.12);
  transform: translateY(-3px);
  color: inherit;
}
.segment-card__img img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.segment-card__img img[src$="rural-array-valley.jpg"] { object-position: 50% 78%; }
.segment-card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 26px 28px 30px;
}
.segment-card__body h3 {
  font-size: 24px;
  font-weight: 700;
  margin: 0 0 10px;
  color: var(--color-heading);
}
.segment-card__body p {
  margin: 0 0 22px;
  color: #3d4540;
  line-height: 1.6;
}
.segment-card__more {
  margin-top: auto;
  font-weight: 700;
  color: var(--brand-green-on-light);
}
.segment-card__more::after { content: " \2192"; }

/* --- Recent work ---------------------------------------------------- */
.recent-work-intro {
  margin: 22px 0 26px;
  font-size: 18px;
  line-height: 1.6;
  color: #3d4540;
}
/* Was a solid black panel, which is nowhere else in the brand. Now a light
   card carrying the project photo, which also works on the white homepage
   section and the white one on /home-solar. */
.project-spec {
  background: #F3F4F5;
  color: #0d0d0d;
  padding: 0 0 34px;
  overflow: hidden;
}
.project-spec__img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  /* 40% keeps the bush hillside behind the array, which is the story. */
  object-position: 50% 40%;
  margin-bottom: 28px;
}
.project-spec__body { padding: 0 40px; }
.project-spec__eyebrow {
  display: block;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-green-on-light);
  margin-bottom: 8px;
}
.project-spec h3 {
  color: #0d0d0d;
  font-size: 30px;
  font-weight: 700;
  margin: 0 0 22px;
}
.project-spec dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 10px 24px;
  margin: 0 0 24px;
}
.project-spec dt { color: #3d4540; font-weight: 500; }
.project-spec dd { margin: 0; font-weight: 600; }
.project-spec p { color: #3d4540; margin: 0 0 24px; line-height: 1.6; }
.project-spec a {
  color: var(--brand-green-on-light);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.project-spec a:hover { color: #145C31; }
@media (max-width: 575px) {
  .project-spec { padding: 0 0 26px; }
  .project-spec__body { padding: 0 24px; }
  .project-spec dl { grid-template-columns: 1fr; gap: 2px; }
  .project-spec dd { margin-bottom: 10px; }
}

/* --- Areas we cover ------------------------------------------------- */
.areas-intro {
  margin: 22px 0 0;
  font-size: 18px;
  line-height: 1.6;
  color: #3d4540;
}
.areas-group {
  background: #ffffff;
  padding: 28px 30px;
  height: 100%;
}
.areas-group h3 {
  font-size: 21px;
  font-weight: 700;
  margin: 0 0 14px;
  color: var(--color-heading);
}
.areas-group ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
.areas-group li {
  position: relative;
  padding-left: 20px;
  color: #3d4540;
}
.areas-group li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-primary);
}
.areas-note {
  margin: 28px 0 0;
  color: #3d4540;
}
.areas-note a {
  color: var(--brand-green-on-light);
  font-weight: 700;
}


/* ---------------------------------------------------------------------------
   "What goes on your house" (home solar)

   Phone: one card per item, its own photo above its own words, so the two
   always arrive together as you scroll.
   Desktop: the items run down the left and a sticky panel on the right
   cross-fades to whichever item you are reading. Both layouts point at the
   same four files, so each is fetched once however many img tags use it.
   --------------------------------------------------------------------------- */
.wgh__stage { display: none; }

.wgh__item + .wgh__item { margin-top: 34px; }

.wgh__inline {
  margin: 0 0 16px;
  border-radius: 10px;
  overflow: hidden;
  background: #ECEEED;
}
.wgh__inline img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
}
.wgh__title {
  margin: 0 0 8px;
  font-size: 21px;
  font-weight: 700;
  line-height: 1.3;
  color: #0d0d0d;
}
.wgh__body {
  margin: 0;
  line-height: 1.65;
  color: #3d4540;
}

/* The first three are square crops made for these slots, so centred is
   right. The fourth is still one of the portrait stock shots, where the
   subject sits low in the frame (see assets/img/weka/MANIFEST.md). */
.wgh__inline img,
.wgh__shot img { object-position: 50% 50%; }
[data-wgh-item="3"] .wgh__inline img,
[data-wgh-media="3"] img { object-position: 50% 66%; }

@media (min-width: 992px) {
  .wgh {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 60px;
    align-items: start;
  }
  .wgh__inline { display: none; }
  .wgh__stage {
    display: block;
    position: sticky;
    top: 120px;
    aspect-ratio: 1 / 1;
    border-radius: 12px;
    overflow: hidden;
    background: #ECEEED;
  }
  .wgh__shot {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    z-index: 1;
    transition: opacity 0.5s ease;
  }
  /* Held at full opacity under the incoming photo for the length of the
     fade, so the panel background never shows through the middle of it. */
  .wgh__shot.is-leaving { opacity: 1; transition: none; }
  .wgh__shot.is-active { opacity: 1; z-index: 2; }
  .wgh__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }

  /* The item you are reading is the one lit up. */
  .wgh__item {
    padding: 4px 0 4px 22px;
    border-left: 3px solid #E4E7E6;
    opacity: 0.45;
    transition: opacity 0.35s ease, border-color 0.35s ease;
    outline-offset: 6px;
  }
  .wgh__item + .wgh__item { margin-top: 52px; }
  .wgh__item.is-active { opacity: 1; border-left-color: var(--color-primary); }
  .wgh__item:hover { opacity: 1; }
}

/* Some people get motion sickness from cross-fades; swap instantly instead. */
@media (prefers-reduced-motion: reduce) {
  .wgh__shot,
  .wgh__item { transition: none; }
}


/* ---------------------------------------------------------------------------
   /home-solar cost factors

   Four paragraphs of near-identical length read as one block of grey, so
   these are short cards the eye can chunk, with the roof-check prompt pulled
   out as its own thing instead of a long closing sentence carrying two
   inline links.
   --------------------------------------------------------------------------- */
.cost-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
}
.cost-card {
  background: #F3F4F5;
  padding: 26px 28px 28px;
  border-top: 3px solid var(--color-primary);
}
.cost-card__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-bottom: 14px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #ffffff;
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
}
.cost-card h3 { margin: 0 0 8px; font-size: 20px; font-weight: 700; line-height: 1.3; color: #0d0d0d; }
.cost-card p { margin: 0; line-height: 1.55; color: #3d4540; }

.cost-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  margin-top: 22px;
  padding: 26px 30px;
  background: #EAF6EE;
  border-left: 4px solid var(--color-primary);
}
.cost-cta__title { margin: 0 0 4px; font-size: 18px; font-weight: 700; color: #0d0d0d; }
.cost-cta p { margin: 0; line-height: 1.55; color: #3d4540; }
.cost-cta .thm-btn { flex: 0 0 auto; }
.loan-source { font-size: 14px; line-height: 1.5; color: #3d4540; }

@media (max-width: 767px) {
  .cost-grid { grid-template-columns: 1fr; gap: 14px; }
  .cost-card { padding: 22px 22px 24px; }
  .cost-cta { flex-direction: column; align-items: flex-start; gap: 18px; padding: 22px 22px; }
  .cost-cta .thm-btn { width: 100%; text-align: center; }
}

/* ---------------------------------------------------------------------------
   /home-solar install process, as one line rather than five cards

   Five cards in a three-wide grid left an orphan row of two and a hole
   beside it. A single line reads in the order the work happens and fits any
   number of steps.
   --------------------------------------------------------------------------- */
.proc-timeline {
  position: relative;
  max-width: 760px;
  margin: 0 auto;
  padding: 0 0 0 78px;
  text-align: left;
}
.proc-timeline::before {
  content: "";
  position: absolute;
  left: 23px;
  top: 10px;
  bottom: 14px;
  width: 2px;
  background: rgba(255, 255, 255, 0.28);
}
.proc-step { position: relative; padding-bottom: 40px; }
.proc-step:last-child { padding-bottom: 0; }
.proc-step__num {
  position: absolute;
  left: -78px;
  top: -6px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: #ffffff;
  color: var(--brand-green-on-light);
  font-size: 19px;
  font-weight: 700;
  line-height: 1;
}
.proc-step__title { margin: 0 0 8px; font-size: 22px; font-weight: 700; line-height: 1.3; color: #ffffff; }
.proc-step__body { margin: 0; line-height: 1.65; color: rgba(255, 255, 255, 0.85); }
.proc-step__body a { color: #ffffff; font-weight: 700; text-decoration: underline; }

@media (max-width: 575px) {
  .proc-timeline { padding-left: 58px; }
  .proc-timeline::before { left: 18px; }
  .proc-step__num { left: -58px; width: 38px; height: 38px; font-size: 16px; top: -3px; }
  .proc-step__title { font-size: 20px; }
  .proc-step { padding-bottom: 32px; }
}

/* Inline links in the recent-work intro were falling back to browser blue. */
.loan-source a,
.recent-work-intro a {
  color: var(--brand-green-on-light);
  font-weight: 600;
  text-decoration: underline;
}


/* ---------------------------------------------------------------------------
   FAQ section spacing

   main.css sets `gap: 313px` on .xb-faq-left, a magic number from the demo
   layout. It pushed "Still have a question?" to the bottom of the column and
   left a third of the section empty. The heading and the prompt belong
   together as one block.

   The questions were also 28px on a 1.14 line-height, heavier than the
   answers beneath them and tight when one wraps.
   --------------------------------------------------------------------------- */
.xb-faq-left { gap: 44px; }

.faq__blockchain .accordion_box .block .acc-btn {
  font-size: 23px;
  line-height: 1.32;
  padding: 22px 52px 22px 0;
}
.faq__blockchain .accordion_box .block .acc-btn .arrow { top: 23px; right: 18px; }
.faq__blockchain .accordion_box .block .acc-btn .arrow::before { font-size: 24px; }

/* Room under an open answer before the rule that follows it. */
.faq__blockchain .accordion_box .block .acc_body { padding-bottom: 26px; }

@media (max-width: 767px) {
  .faq__blockchain .accordion_box .block .acc-btn {
    font-size: 20px;
    padding: 20px 44px 20px 0;
  }
  .faq__blockchain .accordion_box .block .acc-btn .arrow { top: 21px; }
}


/* Inline links in service-page body copy, same treatment as FAQ answers. */
.ser-details-content a,
.xb-content a {
  color: var(--brand-green-on-light);
  font-weight: 600;
  text-decoration: underline;
}

/* FAQ answers can now carry links */
.faq .acc_body .content a {
  color: var(--brand-green-on-light);
  font-weight: 600;
  text-decoration: underline;
}

/* Footer phone number: was an H3, now a paragraph. Keeps the H3 look. */
.xb-footer_info p.xb-item--contact {
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: -0.01em;
}

/* The template capitalises every word in hero titles, which rendered
   "Wellington And Kāpiti Coast" and "Installed To AS/NZS 5033 And 4777".
   Copy is written in the case it should display in. */
.hero-style-one .xb-title,
.trust-strip li {
  text-transform: none;
}

/* main.css sets body { text-transform: capitalize }, which title-cases
   every sentence. New components opt out; the global rule is removed page
   by page as each blueprint step rewrites its copy. */
.how-it-works, .segments, .recent-work, .areas,
.faq .acc-btn, .faq .acc_body, .faq .xb-item--content {
  text-transform: none;
}

/* Homepage copy is written in the case it should display in. */
body.residential_solar main,
body.page-sentence-case main {
  text-transform: none;
}

/* The hero H1 enters with translateX(20px). On a 375px phone that briefly
   pushed the page 8px wider than the viewport, so it could scroll sideways
   during the animation. clip, unlike hidden, creates no scroll container. */
.hero-style-one {
  overflow-x: clip;
}

/* How it works: faded install photo behind the section. The photo sits in a
   pseudo-element at low opacity over the light grey base, so body text and
   the white step cards keep full contrast. */
.how-it-works {
  position: relative;
  isolation: isolate;
}
.how-it-works::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url("../img/weka/solar-roof-sunrise.jpg") center 58% / cover no-repeat;
  opacity: 0.16;
  pointer-events: none;
}
.hiw-steps li {
  box-shadow: 0 6px 22px rgba(13, 13, 13, 0.06);
}

/* Fade the photo out behind the text column. Over the darkest part of the
   roof the green link dropped to about 4:1; on the faded side it keeps its
   full contrast, and the photo still shows behind the step cards. */
.how-it-works::before {
  opacity: 0.22;
  background-position: right 58%;
}
.how-it-works::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, #F3F4F5 0%, #F3F4F5 38%, rgba(243, 244, 245, 0.55) 62%, rgba(243, 244, 245, 0) 100%);
  pointer-events: none;
}
@media (max-width: 991px) {
  .how-it-works::after {
    background: linear-gradient(180deg, #F3F4F5 0%, #F3F4F5 40%, rgba(243, 244, 245, 0.6) 70%, rgba(243, 244, 245, 0.2) 100%);
  }
}

/* How it works, round two: the fade hid most of the photo. The photo now
   shows at real strength and the text sits on its own white panel,
   matching the step cards, so contrast no longer depends on the image. */
.how-it-works::before {
  opacity: 0.6;
  background-position: center 58%;
}
.how-it-works::after {
  content: none;
}
.hiw-panel {
  background: rgba(255, 255, 255, 0.94);
  padding: 44px 42px;
  box-shadow: 0 6px 22px rgba(13, 13, 13, 0.08);
}
@media (max-width: 575px) {
  .hiw-panel { padding: 30px 24px; }
}

/* ================================================================== *
 * Footer, rebuilt
 *
 * The template footer positioned its parts with fixed offsets: a 242px gap,
 * translateY nudges, and a green band of fixed 106px height painted by a
 * pseudo-element. Any copy longer than the demo text pushed "Response time"
 * down into that band and left the social icons floating in it. This is a
 * plain grid that grows with its content.
 * ================================================================== */
.site-footer {
  background: #F3F4F5;
  color: #0d0d0d;
  text-transform: none;
}
.site-footer__grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1.35fr;
  gap: 48px;
  padding: 90px 0 70px;
}
.site-footer h3 {
  font-family: var(--font-heading);
  font-size: 20px;
  font-weight: 600;
  line-height: 1.3;
  margin: 0 0 20px;
  color: #0d0d0d;
}
.site-footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.site-footer__col li + li { margin-top: 10px; }
.site-footer a { color: #0d0d0d; transition: color 0.2s; }
.site-footer__col a:hover { color: var(--brand-green-on-light); }
.site-footer__logo img {
  display: block;
  width: 230px;
  height: auto;
  margin-bottom: 22px;
}
.site-footer__brand p {
  margin: 0 0 24px;
  max-width: 380px;
  line-height: 1.75;
  color: #3d4540;
}
.site-footer__social { display: flex; gap: 10px; }
.site-footer__social a {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(13, 13, 13, 0.1);
}
.site-footer__social a:hover { background: var(--color-primary); color: #ffffff; }
.site-footer__phone {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
  font-family: var(--font-heading);
  font-size: 23px;
  font-weight: 600;
  white-space: nowrap;
}
.site-footer__phone:hover { color: var(--brand-green-on-light); }
.site-footer__phone-icon {
  flex: 0 0 40px;
  height: 40px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-primary);
}
.site-footer__phone-icon img { width: 18px; height: 18px; }
.site-footer__contact p {
  margin: 0 0 12px;
  line-height: 1.6;
  color: #3d4540;
}
.site-footer__contact p a { color: #0d0d0d; }
.site-footer__contact p a:hover { color: var(--brand-green-on-light); }
.site-footer__note { font-size: 15px; }
.site-footer__bottom { background: #225530; }
.site-footer__bottom .container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 24px;
  padding-top: 18px;
  padding-bottom: 18px;
}
.site-footer__bottom p { margin: 0; color: #ffffff; }
.site-footer__bottom ul { display: flex; gap: 22px; }
.site-footer__bottom a { color: #ffffff; }
.site-footer__bottom a:hover { color: #ffffff; text-decoration: underline; }
@media (max-width: 1199px) {
  .site-footer__grid { grid-template-columns: 1fr 1fr 1fr; }
  .site-footer__brand { grid-column: 1 / -1; }
  .site-footer__brand p { max-width: 560px; }
}
@media (max-width: 767px) {
  .site-footer__grid { grid-template-columns: 1fr 1fr; gap: 36px 24px; padding: 64px 0 48px; }
  .site-footer__contact { grid-column: 1 / -1; }
}
@media (max-width: 575px) {
  .site-footer__bottom .container { justify-content: center; text-align: center; }
}

/* --- Form consent notice (replaces the checkbox) ------------------- */
.form-consent {
  margin: 10px 0 0;
  font-size: 15px;
  line-height: 1.6;
  text-align: center;
  text-transform: none;
}
.form-consent a {
  text-decoration: underline;
  text-underline-offset: 3px;
  font-weight: 600;
}
.contact .form-consent,
.contact .form-consent a { color: #ffffff; }
.xb-contact-input-form .form-consent { text-align: left; margin-top: 20px; }

/* logo-weka-full.png carries transparent padding: 6.4% left, 22% top, 20%
   bottom (measured from the alpha channel). At 230px wide that is 15px left
   and ~13px above and below, which indented the logo from the text under it. */
.site-footer__logo img {
  margin: -14px 0 10px -15px;
}

/* Every form sits on a light panel (the homepage one included, inside
   .contact-form), so the notice is dark. The earlier white rule was wrong. */
.contact .form-consent,
.form-consent {
  color: #3d4540;
}
.contact .form-consent a,
.form-consent a {
  color: var(--brand-green-on-light);
}

/* Cloudflare Turnstile slot, inserted above each submit button by
   site-extras.js when Turnstile is switched on. Usually invisible. */
.turnstile-slot {
  display: flex;
  justify-content: center;
}
.turnstile-slot iframe { margin: 12px 0; }

/* --- Hero background video ----------------------------------------------- *
   Sits between the section background photo (poster/fallback) and the
   ::before scrim. Container query units size the 16:9 frame to cover the
   hero at any aspect without JavaScript. */
.hero-video {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
  container-type: size;
  opacity: 0;
  transition: opacity 0.9s ease;
}
.hero-video.is-playing { opacity: 1; }
.hero-video iframe {
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100cqw, 177.78cqh);
  height: max(100cqh, 56.25cqw);
  transform: translate(-50%, -50%);
  border: 0;
}
/* Lighter, directional scrim over video: dark behind the text, footage
   visible to the right. Uniform on narrow screens where text spans the width. */
.hero-style-one.has-video::before {
  background: linear-gradient(90deg, rgba(24, 25, 24, 0.76) 0%, rgba(24, 25, 24, 0.58) 50%, rgba(24, 25, 24, 0.34) 100%) !important;
}
@media (max-width: 991px) {
  .hero-style-one.has-video::before { background: rgba(24, 25, 24, 0.62) !important; }
}

/* Confirmation panel that replaces a form after a successful submit. */
.form-success {
  text-transform: none;
  text-align: center;
  padding: 44px 32px;
  background: #ffffff;
  border-top: 4px solid var(--color-primary);
  outline: none;
}
.form-success__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--color-primary);
  margin-bottom: 18px;
}
.form-success__title {
  font-family: var(--font-heading);
  font-size: 26px;
  font-weight: 700;
  line-height: 1.3;
  color: #0d0d0d;
  margin: 0 0 10px;
}
.form-success__text {
  max-width: 460px;
  margin: 0 auto;
  font-size: 17px;
  line-height: 1.65;
  color: #3d4540;
}
.form-success__text a { color: var(--brand-green-on-light); font-weight: 700; text-decoration: underline; }

/* ================================================================== *
 * About page, rebuilt (blueprint step 7)
 * ================================================================== */
.ab-intro, .ab-alex, .ab-values, .ab-creds { text-transform: none; }
.ab-intro .sec-title, .ab-alex .sec-title { margin-bottom: 22px; }
.ab-lead { font-size: 19px; line-height: 1.65; color: #0d0d0d; margin: 0 0 16px; }
.ab-text { font-size: 17px; line-height: 1.7; color: #3d4540; margin: 0 0 16px; }
.ab-eyebrow {
  display: block;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-green-on-light);
  margin-bottom: 8px;
}

.ab-facts {
  list-style: none;
  margin: 28px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: #D9DEDB;
}
.ab-facts li { background: #ffffff; padding: 18px 16px; }
.ab-facts strong {
  display: block;
  font-family: var(--font-heading);
  font-size: 24px;
  font-weight: 700;
  color: var(--brand-green-on-light);
  line-height: 1.2;
}
.ab-facts span { display: block; font-size: 14px; line-height: 1.45; color: #3d4540; margin-top: 4px; }

/* 4/5 rather than 5/4: the photo here is portrait, and the text column
   beside it runs 690px at 1440 against an image that was rendering 506px,
   so the landscape slot was both wasting the frame and leaving the row
   short. The file is cut to 4/5 already, so object-fit is a safety net
   rather than the thing doing the cropping. */
.ab-intro__img img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 50%;
}

.ab-alex__photo { margin: 0; }
.ab-alex__photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 100%;   /* face and branded fleece sit low in the frame */
}
.ab-alex__photo figcaption {
  margin-top: 10px;
  font-size: 14px;
  color: #3d4540;
}
.ab-alex__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 26px;
  margin-top: 26px;
}
.ab-call {
  font-weight: 700;
  color: var(--brand-green-on-light);
  text-decoration: underline;
  text-underline-offset: 4px;
}
.ab-call:hover { color: #0d0d0d; }

.ab-values__intro {
  max-width: 620px;
  margin: 16px auto 40px;
  text-align: center;
  font-size: 18px;
  line-height: 1.6;
  color: #3d4540;
}
.ab-value {
  height: 100%;
  padding: 30px 28px;
  background: #F3F4F5;
  border-top: 4px solid var(--color-primary);
}
.ab-value__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: var(--color-primary);
  margin-bottom: 18px;
}
.ab-value__icon img { width: 26px; height: 26px; }
.ab-value h3, .ab-cred h3 {
  font-size: 21px;
  font-weight: 700;
  line-height: 1.3;
  color: #0d0d0d;
  margin: 0 0 10px;
}
.ab-value p, .ab-cred p { margin: 0; font-size: 16px; line-height: 1.65; color: #3d4540; }

.ab-cred { height: 100%; padding: 30px 28px; background: #ffffff; }
.ab-cred__logo {
  height: 72px;
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}
.ab-cred__logo img { max-height: 64px; max-width: 200px; width: auto; height: auto; }
.ab-cred__logo--icon span, .ab-cred__logo--icon img {
  width: 54px; height: 54px; padding: 13px;
  border-radius: 50%;
  background: var(--color-primary);
}

@media (max-width: 767px) {
  .ab-facts { grid-template-columns: 1fr; }
  .ab-lead { font-size: 18px; }
}

/* --- Header fit on 1200-1679px screens ------------------------------------ *
   With six top-level items (Tools added) the header needed 1,304px at a
   1280px viewport (logo 309 + menu 755 + phone button 240), so the phone
   button wrapped to a second row at 1280 and 1366. It already wrapped at
   1200 before Tools. Tighter item spacing, 16px menu text and a slimmer phone
   button keep everything on one row down to 1200, with the logo eased down
   at the narrow end. Widened again on 23 Sep 2026 when Blog became a seventh
   menu item. From 1920 up nothing changes. */
@media (min-width: 1200px) and (max-width: 1919px) {
  .header-style-one .header__wrap .main-menu__wrap .main-menu > ul > li { margin-right: 14px; }
  .header-style-one .header__wrap .main-menu__wrap .main-menu > ul > li:last-child { margin-right: 0; }
  .header-style-one .header__wrap .main-menu__wrap .main-menu > ul > li > a { font-size: 16px; }
  .header-area .thm-btn.pd-gradient { padding: 13px 20px; }
}
@media (min-width: 1200px) and (max-width: 1365px) {
  .header-logo img,
  .header-logo .logo1 img { height: 62px; }
  .header-style-one .header__wrap .main-menu__wrap .main-menu > ul > li { margin-right: 10px; }
  .header-style-one .header__wrap .main-menu__wrap .main-menu > ul > li:last-child { margin-right: 0; }
  .header-style-one .header__wrap .main-menu__wrap .main-menu > ul > li > a { font-size: 15px; }
  .header-area .thm-btn.pd-gradient { padding: 12px 16px; font-size: 16px; }
}

/* --- Partners logo strip (homepage), from the live site's "Our Partners" --- */
.partners__title {
  text-align: center;
  font-size: 22px;
  font-weight: 600;
  text-transform: none;
  margin-bottom: 52px;
}
@media (max-width: 575px) {
  .partners__title { margin-bottom: 36px; }
}
.partners__logos {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 30px 60px;
}
.partners__logos img {
  display: block;
  /* Six marks with aspects from 1.55 (Jinko) to 6.21 (Clenergy, a wide
     short wordmark). Sizing on height alone made Clenergy 521px wide
     against Jinko's 130px, so it is capped on both axes: wide marks hit
     the width limit, tall ones the height limit, and the row reads even. */
  height: auto;
  max-height: 60px;
  width: auto;
  /* The widest of the four is EWRB at 400x135, so 84px tall makes it 249px
     wide. max-width has to clear that or the cap shrinks it back below the
     others and the row stops looking level. */
  max-width: 190px;
  object-fit: contain;
}
@media (max-width: 575px) {
  /* Two per row at 390px: 2 x 166 plus a 24px gap plus the container's
     padding still fits, where the desktop size would not. */
  .partners__logos { gap: 22px 24px; }
  .partners__logos img { height: auto; max-height: 44px; max-width: 140px; }
}

/* --- Home solar: live-site benefits list, lenders, form lead ------------- */
.home-benefits li {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  text-transform: none;
  font-size: 17px;
  line-height: 1.6;
}
.home-benefits li + li { margin-top: 18px; }
.home-benefits .xb-check { flex: 0 0 auto; margin: 2px 0 0 0; }
.home-benefits strong { color: var(--color-heading, #111); }
.home-lenders {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.home-lenders a {
  display: inline-block;
  padding: 12px 24px;
  background: #fff;
  border: 1px solid #dfe3e6;
  color: #1f5f33;
  font-weight: 600;
  text-decoration: none;
}
.home-lenders a:hover { border-color: #21a150; }
.contact-lead {
  color: #fff;
  font-size: 18px;
  margin-top: 16px;
  text-transform: none;
}

/* Farm: live-site intro under "Why farmers choose Weka Solar" (black section) */
.farm-why-lead {
  color: rgba(255, 255, 255, 0.85);
  font-size: 18px;
  line-height: 1.7;
  max-width: 760px;
  margin-top: 20px;
  text-transform: none;
}

/* Legal pages (privacy, terms) */
.legal-page .legal-updated {
  color: #5b6168;
  font-size: 15px;
  margin: -10px 0 30px;
}
.legal-page .xb-details-content-item { margin-top: 40px; }
.legal-page .xb-details-content-item p + p,
.legal-page .xb-item--list + p { margin-top: 16px; }
.legal-page .xb-item--list { margin-top: 14px; }
.legal-page .xb-item--list li + li { margin-top: 8px; }
.legal-page a { color: #1f5f33; text-decoration: underline; }
/* main.css capitalises .xb-details-content-wrap p and lowercases its links. */
.legal-page .xb-details-content-wrap,
.legal-page .xb-details-content-wrap p,
.legal-page .xb-details-content-wrap li,
.legal-page .xb-details-content-wrap p a,
.legal-page .xb-details-content-wrap li a { text-transform: none; }
.legal-page .xb-details-content-wrap p a { font-style: normal; }

/* --- Homepage hero on phones and tablets -------------------------------- *
   The "Why choose" panel is pulled up 193px over the hero (.xb-wcu has
   margin-top: -193px). Below 1200px the hero kept a fixed min-height
   (850px on phones) that is shorter than its content, so the panel covered
   the call button and the trust badges. Size the hero to its content and
   leave room for the overlap plus a clear gap. */
@media (max-width: 1199px) {
  .hero-style-one {
    min-height: 0;
    padding-bottom: 260px;
  }
}

/* --- 404 page ------------------------------------------------------------ */
.nf-page__inner { max-width: 760px; }
.nf-page__lead { font-size: 19px; line-height: 1.7; color: #0d0d0d; margin-bottom: 30px; }
.nf-links {
  list-style: none;
  margin: 0 0 40px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
.nf-links a {
  display: block;
  padding: 16px 20px;
  background: #F3F4F5;
  border-left: 3px solid #21a150;
  color: #0d0d0d;
  font-weight: 600;
  text-decoration: none;
}
.nf-links a:hover { background: #e8f5ec; }
.nf-page__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 28px; }
.nf-call { color: #1f5f33; font-weight: 600; text-decoration: underline; }
@media (max-width: 767px) {
  .nf-links { grid-template-columns: 1fr 1fr; }
}
.nf-links a { height: 100%; line-height: 1.4; }

/* --- "Areas we cover" map ------------------------------------------------ *
   An inline SVG coastline of the region (OpenStreetMap data, simplified at
   build time), with a pin per area laid over it as real buttons so the
   keyboard and screen readers get proper controls. No map API, no quota. */
.areas-map {
  position: relative;
  background: #ffffff;
  padding: 24px 20px 40px;
}
.areas-map__svg {
  display: block;
  width: 100%;
  height: auto;
}
.areas-map__coast {
  stroke: #b3bdb6;
  stroke-width: 3;
}
.areas-map__dot {
  fill: #c8d3cb;
  transition: fill 0.2s ease, r 0.2s ease;
}
.areas-map__dot.is-active {
  fill: var(--color-primary);
  r: 11;
}
.areas-map__pin {
  position: absolute;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 6px 6px;
  border: 1px solid #d7ddd9;
  border-radius: 999px;
  background: #ffffff;
  color: var(--color-heading);
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(13, 13, 13, 0.08);
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.areas-map__pin-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--color-primary);
  box-shadow: 0 0 0 4px rgba(33, 161, 80, 0.18);
}
.areas-map__pin:hover,
.areas-map__pin:focus-visible,
.areas-map__pin.is-active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #ffffff;
}
.areas-map__pin:hover .areas-map__pin-dot,
.areas-map__pin:focus-visible .areas-map__pin-dot,
.areas-map__pin.is-active .areas-map__pin-dot {
  background: #ffffff;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.35);
}
.areas-map__credit {
  position: absolute;
  left: 20px;
  bottom: 14px;
  margin: 0;
  font-size: 12px;
  color: #7b847e;
}
.areas-map__credit a { color: #7b847e; text-decoration: underline; }

/* Area cards: the heading is the control, so the whole card can highlight. */
.areas-group { transition: box-shadow 0.2s ease, transform 0.2s ease; }
.areas-group.is-active {
  box-shadow: inset 4px 0 0 var(--color-primary), 0 10px 30px rgba(13, 13, 13, 0.08);
}
.areas-group__btn {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-align: left;
}
.areas-group__btn:hover,
.areas-group__btn:focus-visible { color: var(--brand-green-on-light); }

@media (max-width: 991px) {
  .areas-map { padding: 16px 14px 34px; }
  .areas-map__pin { font-size: 12px; padding: 5px 10px 5px 5px; }
  .areas-map__pin-dot { width: 11px; height: 11px; }
}
@media (prefers-reduced-motion: reduce) {
  .areas-map__pin, .areas-map__dot, .areas-group { transition: none; }
}
/* Pins near an edge anchor inward so their label cannot overflow the card. */
.areas-map__pin--left { transform: translate(0, -50%); }
.areas-map__pin--right { transform: translate(-100%, -50%); }
/* Heading and intro sit across the top, the closing line below both columns. */
.areas-head { max-width: 760px; margin-bottom: 10px; }
.areas-head .areas-intro { margin-top: 18px; }
.areas .areas-note { margin-top: 40px; max-width: 860px; }

/* On phones the cards read first; the map follows them. */
@media (max-width: 991px) {
  .areas .row > .col-lg-5 { order: 2; }
  .areas .row > .col-lg-7 { order: 1; }
}

/* --- "Areas we cover" background photo ----------------------------------- *
   A countryside roof array sits behind the section, almost washed out by a
   white veil so the white cards and the map still read cleanly. Swap the
   photo by changing --areas-bg only. */
.areas--photo {
  position: relative;
  background-image: var(--areas-bg, url("../img/weka/rural-array-valley.jpg"));
  background-size: cover;
  background-position: center 40%;
  background-repeat: no-repeat;
}
.areas--photo::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.78);
  pointer-events: none;
}
.areas--photo > .container { position: relative; z-index: 1; }
@media (max-width: 991px) {
  /* A tall phone stretches a cover photo into mush, and the veil hides it
     anyway, so keep it fixed to the top of the section. */
  .areas--photo { background-position: center top; }
}

/* Footer credit line, between the copyright and the legal links. */
.site-footer__credit { margin: 0; color: #ffffff; }
.site-footer__credit a { text-decoration: underline; }

/* Projects page intro, under the banner. */
.projects-intro__inner { max-width: 860px; }
.projects-intro__title {
  font-size: 34px;
  line-height: 1.25;
  margin: 0 0 22px;
  text-transform: none;
}
.projects-intro p {
  font-size: 18px;
  line-height: 1.7;
  color: #3d4540;
  text-transform: none;
}
.projects-intro p + p { margin-top: 16px; }
.projects-intro a { color: var(--brand-green-on-light); font-weight: 600; }
@media (max-width: 767px) {
  .projects-intro__title { font-size: 27px; }
}
@media (max-width: 767px) {
  /* Keep the floating back-to-top button off the credit line. */
  .site-footer__bottom .container { padding-bottom: 54px; }
}

/* --- Blog hub and articles ----------------------------------------------- */
.blog-list__intro { max-width: 760px; font-size: 18px; line-height: 1.7; color: #3d4540; }
.blog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 40px 30px;
  margin-top: 50px;
}
.blog-card { background: #ffffff; box-shadow: 0 10px 30px rgba(13, 13, 13, 0.06); }
.blog-card__img { display: block; aspect-ratio: 16 / 10; overflow: hidden; }
.blog-card__img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s ease; }
.blog-card:hover .blog-card__img img { transform: scale(1.04); }
.blog-card__body { padding: 26px 28px 30px; }
.blog-card__meta { margin: 0 0 10px; font-size: 14px; color: #6b736d; }
.blog-card__title { font-size: 24px; line-height: 1.3; margin: 0 0 12px; }
.blog-card__title a { color: var(--color-heading); }
.blog-card__title a:hover { color: var(--brand-green-on-light); }
.blog-card__body p { color: #3d4540; line-height: 1.6; }
.blog-card__more { display: inline-block; margin-top: 16px; font-weight: 700; color: var(--brand-green-on-light); }
.blog-list__note { margin-top: 44px; color: #3d4540; }
.blog-list__note a { color: var(--brand-green-on-light); font-weight: 700; }

.article__inner { max-width: 760px; }
.article__meta { font-size: 14px; color: #6b736d; margin-bottom: 18px; }
.article__lead { font-size: 21px; line-height: 1.6; color: var(--color-heading); font-weight: 600; }
.article__inner h2 { font-size: 30px; line-height: 1.3; margin: 46px 0 16px; }
.article__inner p { font-size: 18px; line-height: 1.75; color: #3d4540; }
.article__inner p + p { margin-top: 16px; }
.article__inner a { color: var(--brand-green-on-light); font-weight: 600; }
.article__list { margin: 18px 0 0; padding: 0; list-style: none; }
.article__list li {
  position: relative;
  padding-left: 22px;
  font-size: 18px;
  line-height: 1.7;
  color: #3d4540;
}
.article__list li + li { margin-top: 12px; }
.article__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-primary);
}
.article__cta { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 26px; margin: 34px 0 0; }
.article__call { color: var(--brand-green-on-light); font-weight: 700; text-decoration: underline; }
.article__source { margin-top: 40px; font-size: 14px; color: #6b736d; }
.article__source a { color: #6b736d; font-weight: 400; text-decoration: underline; }
.blog-list, .article { text-transform: none; }
@media (max-width: 767px) {
  .article__inner h2 { font-size: 25px; }
  .article__lead { font-size: 19px; }
}

/* --- Mobile header call button ------------------------------------------ *
   Sits left of the hamburger and dials the number. Mirrors the hamburger's
   sizing and its colour change when the sticky bar turns white. */
.header-bar-mobile { display: flex; align-items: center; gap: 16px; }
.xb-call-mobile,
.xb-nav-mobile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  padding: 0;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.08);
  color: var(--color-primary);          /* the green accent marks both as controls */
}
.xb-call-mobile svg { display: block; }
.xb-call-mobile:hover,
.xb-call-mobile:focus-visible,
.xb-nav-mobile:hover { border-color: var(--color-primary); background: rgba(33, 161, 80, 0.16); color: var(--color-primary); }
/* On the white sticky bar the frame goes dark green so it still reads as a button. */
.header-style-one .stricked-menu .xb-call-mobile,
.header-style-one .stricked-menu .xb-nav-mobile {
  border-color: rgba(38, 88, 46, 0.35);
  background: rgba(33, 161, 80, 0.08);
  color: var(--color-primary);
}

/* --- Logo aspect ratio on phones ----------------------------------------- *
   main.css caps these logos by width (85% and 170px) while we cap by height,
   which squashed the 1999x544 wordmark. Height wins, width follows. */
@media (max-width: 767px) {
  .header-area .header__wrap .header-logo a img,
  .xb-logo-mobile a img { max-width: none; }
}

/* ==================================================================== *
 * Page banner and mobile layout pass, 23 Sep 2026
 *
 * The template's inner-page banner was 400 to 550px tall with another
 * 110 to 150px of padding inside it, and it centred the breadcrumb under
 * a huge H1. On a phone that was most of the first screen with nothing
 * in it. Banner is now shorter, left aligned, with a small breadcrumb
 * trail above the heading where it belongs.
 * ==================================================================== */
.breadcrumb {
  min-height: 0;
  padding: 190px 0 90px;
  align-items: flex-end;
}
.breadcrumb__content {
  padding-top: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
}
.breadcrumb__list {
  order: -1;                 /* trail above the H1 */
  display: flex;
  flex-wrap: wrap;
  margin: 0 0 14px;
}
.breadcrumb__list li {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.82);
}
.breadcrumb__list li a { color: rgba(255, 255, 255, 0.82); }
.breadcrumb__list li a:hover { color: #ffffff; }
.breadcrumb__title { margin-bottom: 0; }
@media (max-width: 1199px) {
  .breadcrumb { padding: 150px 0 70px; }
  .breadcrumb__content { text-align: left; align-items: flex-start; }
}
@media (max-width: 767px) {
  .breadcrumb { padding: 110px 0 44px; }
  .breadcrumb__title { font-size: 32px; line-height: 1.15; }
  .breadcrumb__list li { font-size: 12px; }
}

/* The template's section padding is 110 to 140px top and bottom, which on
   a phone reads as one long scroll of empty space. */
@media (max-width: 767px) {
  .pt-170, .pt-165, .pt-160, .pt-150, .pt-145, .pt-140, .pt-135, .pt-130, .pt-125, .pt-120, .pt-115, .pt-110 { padding-top: 64px; }
  .pb-170, .pb-165, .pb-160, .pb-150, .pb-145, .pb-140, .pb-135, .pb-130, .pb-125, .pb-120, .pb-115, .pb-110 { padding-bottom: 64px; }
  .mt-60, .mt-55, .mt-50 { margin-top: 32px; }
  .mb-60, .mb-55, .mb-50, .mb-45 { margin-bottom: 28px; }
  .pt-60, .pt-50 { padding-top: 32px; }
  .pb-60, .pb-50 { padding-bottom: 32px; }
}

/* Long copy reads badly centred on a narrow screen: ragged on both sides
   and no consistent left edge to come back to. */
@media (max-width: 767px) {
  .xb-project-wrap.text-center,
  .xb-project-wrap.text-center .sec-title,
  .segments .sec-title.text-center,
  .installation-process .sec-title.text-center,
  .ab-values .sec-title.text-center {
    text-align: left;
  }
  .segments-lead,
  .ab-values__intro,
  .installation-process .sec-title p { margin-left: 0; margin-right: 0; }
  .ser-installation-process-item { text-align: left; }
}

/* This parallax section was locked to 1182px tall, which left roughly half
   a screen of empty photo under its content. Padding sets the height now. */
.project-bg { min-height: 0; }

/* Headings on a phone: the template jumps straight from 60px to 36px. */
@media (max-width: 767px) {
  .sec-title .title,
  .sec-title--two .title,
  .sec-title--three .title,
  .xb-title { font-size: 30px; line-height: 1.22; }
  .xb-details-title, .item_details_heading { font-size: 25px; line-height: 1.25; }
  .xb-item--title { font-size: 20px; }
}

/* Projects grid: only the Bull Creek tile is a link now, so the others must
   still look deliberate, and each tile carries a one-line caption. */
.project-single-item .image { display: block; overflow: hidden; }
.project-single-item__sub { margin: 6px 0 0; font-size: 15px; color: #6b736d; }

/* The copy in this section is centred by the template; on a phone that is
   hard to read, so it aligns left with everything else. */
@media (max-width: 767px) {
  .xb-project-wrap .content-one,
  .xb-project-wrap .content-two,
  .xb-project-wrap .project-btn { text-align: left; }
}

/* --- Reveal animation fallback ------------------------------------------- *
   main.js runs WOW with mobile: false, so on a phone the "animated" class is
   never added. .skewInImg hides its image in CSS until that class arrives
   (clip-path collapsed to zero width), so several photos simply never
   appeared on mobile. Below the WOW cut-off the images just show. */
@media (max-width: 991px) {
  .skewInImg { clip-path: none; transition: none; }
  .skewInImg img { transform: none; transition: none; }
}

/* Farm overview paragraph was 30px on a phone, which reads as a wall. */
@media (max-width: 767px) {
  .sec-title--three .content,
  .ps-about-wrap .content { font-size: 18px; line-height: 1.65; }
  .xb-details-title.text-center,
  h3.xb-details-title.text-center { text-align: left; }
}

/* The commercial form heading rendered in caps; copy is written in the case
   it should display in. */
.contact .title.text-anime,
.commercial_solar .contact .title { text-transform: none; }

/* Feature tiles are links now, so they need a pointer and a hover state. */
a.xb-feature-item { display: block; color: inherit; }
a.xb-feature-item:hover .xb-item--title { text-decoration: underline; }
/* Commercial form button matched the rest of the site's buttons. */
.commercial_solar .contact button[type="submit"],
/* The submit button is the green fill on every contact section, so its
   label is white everywhere. This was scoped to .commercial_solar, which
   meant the farm page's copy of the same form rendered black on green,
   about 2.6:1. Stated once for all pages so it cannot drift again. */
.contact .thm-btn,
.contact button[type="submit"] { color: #ffffff; }

/* Farm CTA band: the template gave it 824px minimum height and 270px of
   padding, which is most of a phone screen of empty photo. */
.cta-bg { min-height: 0; padding: 150px 0; }
@media (max-width: 991px) { .cta-bg { padding: 90px 0; } }
@media (max-width: 767px) { .cta-bg { padding: 64px 0; } }
.cta-content .title { text-transform: none; }

/* Home solar: the two photos beside "Benefits of going solar" came out at
   different sizes and sat unevenly. Equal columns, matched crop. */
.ser-benefit-item-img { display: flex; gap: 20px; align-items: stretch; }
.ser-benefit-item-img .img { flex: 1 1 0; display: block; }
.ser-benefit-item-img .img img {
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
@media (max-width: 575px) {
  .ser-benefit-item-img { flex-direction: column; gap: 16px; }
}

/* Mobile header: a little shorter. The logo drives the row height, so it
   comes down with it, and the two buttons shrink to match. */
@media (max-width: 1199px) {
  .header-logo img,
  .xb-logo-mobile img,
  .xb-item--logo img { height: 56px; }
  .xb-header .header__wrap,
  .header-logo { min-height: 68px; }
  .xb-call-mobile,
  .xb-nav-mobile { width: 42px; height: 42px; }
}
@media (max-width: 575px) {
  .header-logo img,
  .xb-logo-mobile img,
  .xb-item--logo img { height: 44px; }
  .xb-header .header__wrap,
  .header-logo { min-height: 56px; }
  .xb-call-mobile,
  .xb-nav-mobile { width: 40px; height: 40px; }
  .header-bar-mobile { gap: 12px; }
}

/* --- "Why choose Weka Solar" carousel on phones --------------------------- *
   Six stacked cards made this section a very long scroll on a phone. Below
   768px they become one horizontal, snapping track that advances on a timer
   (see startWcuCarousel in site-extras.js). The track only pans sideways:
   overflow-y stays hidden and touch-action is pan-x, so a swipe cannot drag
   the cards up and down inside their own box. */
@media (max-width: 767px) {
  .xb-wcu-wrap {
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
    overflow-x: auto;
    overflow-y: hidden;
    touch-action: pan-x pan-y;   /* a vertical drag still scrolls the page */
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 16px;
    /* One card at a time, filling the green panel. Neighbouring cards sit
       outside the scroller's box, so nothing peeks past the panel edge. */
    margin: 30px 0 0;
    padding: 0;
  }
  .xb-wcu-wrap::-webkit-scrollbar { display: none; }
  /* main.css slides this paragraph down 30px with a transform, which eats
     the space above the cards without taking any room in the layout. */
  .xb-wcu-top .wcu-content { transform: none; }
  .xb-wcu-wrap > [class*="col-"] {
    flex: 0 0 100%;
    width: 100%;
    max-width: 100%;
    margin: 0;
    padding: 0;
    scroll-snap-align: center;
    display: flex;
  }
  .xb-wcu-wrap .xb-wcu-item {
    margin: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
    padding: 26px 24px 24px;
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid rgba(255, 255, 255, 0.14);
  }
  .xb-wcu-wrap .xb-wcu-item .xb-item--icon { height: 52px; width: 52px; }
  .xb-wcu-wrap .xb-wcu-item .xb-item--icon img { width: 26px; height: 26px; }
  .xb-wcu-wrap .xb-wcu-item .xb-item--title {
    font-size: 21px;
    line-height: 1.25;
    margin: 18px 0 10px;
  }
  .xb-wcu-wrap .xb-wcu-item .xb-item--content {
    font-size: 16px;
    line-height: 1.6;
    margin: 0;
  }
  .wcu-dots {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 7px;
    margin-top: 20px;
  }
  .wcu-dots button {
    width: 7px;
    height: 7px;
    padding: 0;
    border: 0;
    border-radius: 99px;
    background: rgba(255, 255, 255, 0.4);
    transition: width 0.25s ease, background 0.25s ease;
  }
  .wcu-dots button.is-active {
    width: 22px;
    background: #ffffff;
  }
}
@media (min-width: 768px) {
  .wcu-dots { display: none; }
}
/* Card titles are written in the case they should read in. */
.xb-wcu-item .xb-item--title { text-transform: none; }

/* Source line under the three solar facts on the homepage. */
.fanfact-source {
  margin: 18px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.75);
}
.fanfact-source a { color: rgba(255, 255, 255, 0.75); text-decoration: underline; }
.fanfact-source a:hover { color: #ffffff; }
.fanfact-lead {
  margin: 26px 0 0;
  font-size: 17px;
  line-height: 1.6;
  color: #ffffff;
}
@media (max-width: 767px) {
  /* "2,000+" was wrapping its plus sign onto a second line. */
  .xb-fanfact-wrap .xb-item--number { font-size: 34px; white-space: nowrap; }
  .xb-fanfact-wrap .xb-item--content { font-size: 15px; line-height: 1.5; }
}

/* Project tiles: the title sat 25px below the photo. The template puts that
   margin on the link inside the h3, which collapses through the heading, so
   nothing set on the h3 itself could move it. */
.project-single-item .image img { display: block; width: 100%; }
.project-single-item h3 a { margin-top: 0; display: block; }
.project-single-item h3 { margin-top: 14px; line-height: 1.25; }
.project-single-item__sub { margin-top: 4px; }

/* ---------------------------------------------------------------------------
   /home-solar "Solar designed around your roof..."

   The photos rendered 366x0 on phones, so they were simply not there:
   `height: 100%` needs a parent with a resolved height, and once the flex
   direction turns to column there is none, so it computes to zero. The
   aspect-ratio already matches the two columns, so height can be auto.

   Spacing down the section was also uneven: 10px between the hero photo and
   the heading under it, 25px before the benefit block, against 60px
   elsewhere, and on phones the two were touching at -2px.
   --------------------------------------------------------------------------- */
.ser-benefit-item-img .img img { height: auto; }
/* flex: 1 1 0 gives the wrapper a zero basis on the main axis. That is the
   width in a row and the HEIGHT once the direction turns to column, and
   nothing stretches it back, so the wrappers stayed 0 tall on phones even
   though the images inside them were fine. */
@media (max-width: 575px) {
  .ser-benefit-item-img .img { flex: 0 0 auto; }
}

/* .row.mt-none-30 inside this block has a -30px top margin that would
   otherwise collapse through and eat the gap above it. */
.serivce-benefit { display: flow-root; }
.service-details-img { margin-bottom: 60px; }
.serivce-overview { margin-bottom: 60px; }

/* "Adding a battery": text beside the photo rather than text alone. */
.battery-block {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 44px;
  align-items: center;
}
.battery-block__img { margin: 0; }
.battery-block__img img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: 50% 60%;
}

@media (max-width: 767px) {
  .service-details-img { margin-bottom: 32px; }
  .serivce-overview { margin-bottom: 32px; }
  .battery-block { grid-template-columns: 1fr; gap: 24px; }
  .battery-block__img { order: -1; }
}

/* ---------------------------------------------------------------------------
   In-page anchors

   Free-quote CTAs now jump to the form on the same page where there is one.
   The header is sticky, so a plain jump puts the section heading underneath
   it; scroll-margin-top reserves the space. Smooth only for people who have
   not asked for less motion.
   --------------------------------------------------------------------------- */
#quote,
#rc-lead,
#installation-process { scroll-margin-top: 112px; }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
@media (max-width: 1199px) {
  #quote,
  #rc-lead,
  #installation-process { scroll-margin-top: 104px; }
}

/* ---------------------------------------------------------------------------
   Homepage "Why choose Weka Solar"

   main.css puts margin-top: 63px on every card, which with the old ragged
   card heights opened a 127px trench between the two rows. The copy is now
   even, so a smaller, consistent gap works.
   --------------------------------------------------------------------------- */
.xb-wcu-item { margin-top: 48px; }
.xb-wcu-top .wcu-content { margin-bottom: 0; }
.xb-wcu-item .xb-item--content { max-width: 34ch; }

@media (max-width: 991px) {
  .xb-wcu-item { margin-top: 36px; }
  .xb-wcu-item .xb-item--content { max-width: none; }
}

/* ---------------------------------------------------------------------------
   Homepage "Why choose Weka Solar" panel

   The demo pulled this 193px up over the hero and inset it 120px a side,
   which left it floating with wide empty bands and covering the hero's
   trust strip. Overlap is now 72px and the inset is tighter and the same
   at every width. The intro's translateY(40px) is dropped so it sits with
   the heading instead of below it.
   --------------------------------------------------------------------------- */
.xb-wcu {
  margin-top: -72px;
  margin-left: 56px;
  margin-right: 56px;
  padding-left: 0;
  padding-right: 0;
}
.xb-wcu-top .wcu-content {
  transform: none;
  padding-left: 0;
  margin-right: 0;
}
.xb-wcu-top { margin-bottom: 8px; }

@media only screen and (min-width: 1200px) and (max-width: 1500px) {
  .xb-wcu { margin-left: 40px; margin-right: 40px; padding-left: 0; }
}
@media (max-width: 1199px) {
  .xb-wcu { margin-left: 20px; margin-right: 20px; padding-left: 0; padding-right: 0; }
  /* The hero reserved room for the old 193px overlap. */
  .hero-style-one { padding-bottom: 150px; }
}

/* A hairline over each card so the two rows read as a grid rather than six
   things floating on green. Above the phone carousel breakpoint only: below
   it these become swipeable cards with their own surface. */
@media (min-width: 768px) {
  .xb-wcu-item {
    margin-top: 0;
    padding: 30px 26px 4px 0;
    border-top: 1px solid rgba(0, 0, 0, 0.16);
  }
  .xb-wcu-wrap > [class*="col-"] { margin-top: 26px; }
  .xb-wcu-item .xb-item--icon { margin-bottom: 18px; }
}

/* ---------------------------------------------------------------------------
   "Why choose" panel on phones and tablets

   The overlap is a desktop effect: on a narrow screen it is just 72px of
   empty green above the heading, and the hero has to reserve space for it
   as well. Both go. Padding comes down to match, and the intro tightens
   from an 18/32 (1.78) to something that suits a five-line wrap.
   --------------------------------------------------------------------------- */
@media (max-width: 1199px) {
  .xb-wcu { margin-top: 0; }
  .hero-style-one { padding-bottom: 56px; }
}

@media (max-width: 767px) {
  .xb-wcu.pt-90 { padding-top: 40px; }
  .xb-wcu.pb-70 { padding-bottom: 36px; }
  .xb-wcu-top { margin-bottom: 0; }
  .xb-wcu-top .wcu-content {
    font-size: 17px;
    line-height: 1.6;
    margin-top: 12px;
  }
  .xb-wcu .sec-title .title { margin-bottom: 0; }
}

/* The panel's heading, intro and cards sat 12px inside the green edge on a
   phone, which is too tight for a full-bleed colour block. Widened on small
   screens only: on desktop the panel is already inset 40 to 56px from the
   page, and 15px here is what keeps its heading on the same vertical as the
   hero H1 (both land on 155px at 1600). */
@media (max-width: 991px) {
  .xb-wcu > .container { padding-left: 26px; padding-right: 26px; }
}

/* ===========================================================================
   Mobile type scale

   A render audit at 390px found 24 different body-text styles between 12px
   and 20px, with leading from 1.4 to 2.67, and 18 heading styles including
   H2 at 40, 35, 32, 30, 28, 27, 25 and 24px. Body copy in the same role was
   coming out at 18/1.78, 18/1.65, 18/1.6, 17/1.6 and 16/1.6 on different
   pages, which is what makes the text look like it keeps changing size.

   One scale, applied last so it wins on source order.
   =========================================================================== */
@media (max-width: 767px) {
  main p,
  main li,
  main dd,
  main .xb-item--content,
  main .ser-details-content,
  main .xb-content,
  main .wcu-content,
  main .acc_body .content,
  main .xb-details-content-wrap p {
    font-size: 17px !important;
    line-height: 1.6 !important;
  }

  /* Anything deliberately secondary stays smaller, but not below 14px. */
  main .form-consent,
  main .rc-source,
  main .loan-source,
  main .fanfact-source,
  main .rc-tel__hint,
  main .areas-map__credit,
  main .trust-strip li,
  main .blog-meta,
  main .project-single-item__sub { font-size: 14px !important; line-height: 1.5 !important; }

  main h1, main h1.xb-title, main .breadcrumb__title { font-size: 34px !important; line-height: 1.2 !important; }
  main h2, main .sec-title h2.title, main h2.xb-title { font-size: 26px !important; line-height: 1.25 !important; }
  main h3 { font-size: 20px !important; line-height: 1.3 !important; }
  main h4 { font-size: 18px !important; line-height: 1.35 !important; }

  /* A heading and the text under it were landing 0 to 14px apart in
     seventy-odd places. One value, everywhere. */
  main h2, main h2.xb-title { margin-bottom: 14px !important; }
  /* A lead paragraph under a section heading wants a touch more room
     than a heading sitting directly on body copy. */
  main .sec-title h2.title, main .sec-title .title { margin-bottom: 18px !important; }
  main h3, main h4 { margin-bottom: 10px !important; }
  /* Was margin-bottom: 0 !important, which also killed the mb-* utilities
     on these blocks: measured at 390px every .sec-title reported 0px and
     a centred lead sat flush against the block below it, against 60px at
     desktop. The utilities come back, scaled down, and the baseline is a
     real value rather than 0, because plenty of .sec-title blocks carry no
     mb-* class at all and were running straight into the next element.
     These sit inside flex rows, where sibling margins do not collapse, so
     the value is deliberately modest. */
  main .sec-title { margin-bottom: 26px; }
  main .sec-title.mb-20 { margin-bottom: 18px; }
  main .sec-title.mb-25 { margin-bottom: 20px; }
  main .sec-title.mb-30 { margin-bottom: 24px; }
  main .sec-title.mb-40 { margin-bottom: 30px; }
  main .sec-title.mb-45 { margin-bottom: 32px; }
  main .sec-title.mb-50 { margin-bottom: 34px; }
  main .sec-title.mb-60 { margin-bottom: 40px; }
}

/* The submit button: padding was 25px 100px below 768px, so on a 360px
   screen 200px of the button's 276px was padding and the label wrapped to
   three lines. */
@media (max-width: 767px) {
  .contact-btn button {
    padding: 18px 24px;
    font-size: 17px !important;
    width: 100%;
  }
}

/* Desktop keeps its larger type, but the heading-to-text gap was just as
   tight there, so that part applies at every width. */
@media (min-width: 768px) {
  main h2, main .sec-title h2.title, main h2.xb-title { margin-bottom: 18px !important; }
  main h3, main h4 { margin-bottom: 12px !important; }
}

/* farm-solar: main.css puts margin-top: 250px on .about-right-content below
   768px, a demo-layout offset for an overlap this page does not have, so it
   rendered as a quarter-screen of blank between the cards and the photo.
   Fixed here rather than in main.css, which has no cache-busting query. */
@media (max-width: 767px) {
  .about-right-content { margin-top: 30px; }
}

/* ===========================================================================
   Icons without Font Awesome

   fontawesome.css (106 KB) and three .ttf files (1.00 MB) were loading on
   every page so the site could draw ten shapes. Measured on the homepage,
   fonts were 0.98 MB of a 2.35 MB same-origin payload, competing with the
   hero video for one mobile connection.

   Same markup, same selectors. These are masks tinted with currentColor, so
   they inherit colour and size the way the glyphs did. Drawn here rather
   than taken from Font Awesome Pro, which is licensed.

   Keyed on the shape classes by name, never on [class*="fa-"], because the
   markup puts a style prefix on the same element (fa-brands fa-instagram)
   and that prefix must not be given a box of its own.
   =========================================================================== */
.fa-bars,
.fa-arrow-up,
.fa-angle-right,
.fa-facebook-f,
.fa-instagram {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
  background-color: currentColor;
  background-image: none;
}
.fa-bars::before,
.fa-arrow-up::before,
.fa-angle-right::before,
.fa-facebook-f::before,
.fa-instagram::before { content: none; }

.fa-bars {
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3 6h18v2.1H3zM3 11h18v2.1H3zM3 16h18v2.1H3z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3 6h18v2.1H3zM3 11h18v2.1H3zM3 16h18v2.1H3z'/%3E%3C/svg%3E") no-repeat center / contain;
}
.fa-arrow-up {
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3.2l7.1 7.1-1.5 1.5-4.5-4.5V21h-2.2V7.3l-4.5 4.5-1.5-1.5z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3.2l7.1 7.1-1.5 1.5-4.5-4.5V21h-2.2V7.3l-4.5 4.5-1.5-1.5z'/%3E%3C/svg%3E") no-repeat center / contain;
}
.fa-angle-right {
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8.9 4.6l1.6-1.6 9 9-9 9-1.6-1.6L16.3 12z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8.9 4.6l1.6-1.6 9 9-9 9-1.6-1.6L16.3 12z'/%3E%3C/svg%3E") no-repeat center / contain;
}
.fa-facebook-f {
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M15.6 12.9h-2.7V21h-3.3v-8.1H7.4V9.8h2.2V7.9c0-2.7 1.4-4.4 4.3-4.4 .9 0 1.8.1 2.5.2v2.9h-1.6c-1.2 0-1.9.5-1.9 1.7v1.5h3z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M15.6 12.9h-2.7V21h-3.3v-8.1H7.4V9.8h2.2V7.9c0-2.7 1.4-4.4 4.3-4.4 .9 0 1.8.1 2.5.2v2.9h-1.6c-1.2 0-1.9.5-1.9 1.7v1.5h3z'/%3E%3C/svg%3E") no-repeat center / contain;
}
.fa-instagram {
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 3h8a5 5 0 0 1 5 5v8a5 5 0 0 1-5 5H8a5 5 0 0 1-5-5V8a5 5 0 0 1 5-5zm0 2.1A2.9 2.9 0 0 0 5.1 8v8A2.9 2.9 0 0 0 8 18.9h8a2.9 2.9 0 0 0 2.9-2.9V8A2.9 2.9 0 0 0 16 5.1zm4 2.6a4.3 4.3 0 1 1 0 8.6 4.3 4.3 0 0 1 0-8.6zm0 2.1a2.2 2.2 0 1 0 0 4.4 2.2 2.2 0 0 0 0-4.4zm4.9-2.9a1.15 1.15 0 1 1 0 2.3 1.15 1.15 0 0 1 0-2.3z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 3h8a5 5 0 0 1 5 5v8a5 5 0 0 1-5 5H8a5 5 0 0 1-5-5V8a5 5 0 0 1 5-5zm0 2.1A2.9 2.9 0 0 0 5.1 8v8A2.9 2.9 0 0 0 8 18.9h8a2.9 2.9 0 0 0 2.9-2.9V8A2.9 2.9 0 0 0 16 5.1zm4 2.6a4.3 4.3 0 1 1 0 8.6 4.3 4.3 0 0 1 0-8.6zm0 2.1a2.2 2.2 0 1 0 0 4.4 2.2 2.2 0 0 0 0-4.4zm4.9-2.9a1.15 1.15 0 1 1 0 2.3 1.15 1.15 0 0 1 0-2.3z'/%3E%3C/svg%3E") no-repeat center / contain;
}

/* main.css draws these from the font by codepoint. Same selectors, same
   sizes, mask instead of a glyph. */

/* FAQ accordion, \f067 and \f068 */
.faq__blockchain .accordion_box .block .acc-btn .arrow::before {
  content: "";
  width: 26px;
  height: 26px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10.9 3.5h2.2v7.4H21v2.2h-7.9V21h-2.2v-7.9H3v-2.2h7.9z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10.9 3.5h2.2v7.4H21v2.2h-7.9V21h-2.2v-7.9H3v-2.2h7.9z'/%3E%3C/svg%3E") no-repeat center / contain;
}
.faq__blockchain .accordion_box .block.active-block .acc-btn .arrow::before {
  /* main.css sets content to a codepoint on the active block too, and that
     rule outranks the base one above, so it has to be cleared here as well.
     The first FAQ item ships with active-block, so this is the open item on
     every page that has a FAQ. */
  content: "";
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3 10.9h18v2.2H3z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3 10.9h18v2.2H3z'/%3E%3C/svg%3E");
}

/* Mobile menu parent toggle, appended by main.js:89-90, \f107 and \f106 */
.xb-menu-toggle::before {
  content: "";
  display: block;
  width: 1em;
  height: 1em;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.6 8.9l-1.6 1.6 9 9 9-9-1.6-1.6L12 16.3z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.6 8.9l-1.6 1.6 9 9 9-9-1.6-1.6L12 16.3z'/%3E%3C/svg%3E") no-repeat center / contain;
}
.xb-menu-toggle.active::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.6 15.1l-1.6-1.6 9-9 9 9-1.6 1.6L12 7.7z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.6 15.1l-1.6-1.6 9-9 9 9-1.6 1.6L12 7.7z'/%3E%3C/svg%3E");
}

/* Nested submenu caret, \f0d7 */
.main-menu ul li ul.submenu .menu-item-has-children > a span::after {
  content: "";
  width: 13px;
  height: 13px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 17L4.5 8h15z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 17L4.5 8h15z'/%3E%3C/svg%3E") no-repeat center / contain;
}

/* The back-to-top button is position: fixed at right 30px / bottom 40px, so
   at the very bottom of the page it lands on top of the last line of the
   footer. Measured at 390px: the button occupies x 320-360 and the Privacy
   Policy link runs to x 343, so the button covered the end of it on every
   page. Clearing a lane for it below the legal links. */
@media (max-width: 767px) {
  .site-footer__bottom { padding-bottom: 64px; }
}

/* Tables inside an article. The Wellington guide is the first page to use
   real data tables, so they need a style that stays readable at 390px
   without a horizontal scrollbar. */
.article__table {
  width: 100%;
  border-collapse: collapse;
  margin: 26px 0 30px;
  font-size: 16px;
}
.article__table caption {
  caption-side: bottom;
  padding-top: 10px;
  font-size: 14px;
  color: #6b7280;
  text-align: left;
}
.article__table th,
.article__table td {
  padding: 10px 12px;
  border-bottom: 1px solid #e5e7eb;
  text-align: left;
  vertical-align: top;
}
.article__table thead th {
  border-bottom: 2px solid #d1d5db;
  font-weight: 700;
  white-space: nowrap;
}
.article__table tbody th[scope="row"] { font-weight: 700; }
.article__table tbody tr:last-child th,
.article__table tbody tr:last-child td { border-bottom: none; }
@media (max-width: 575px) {
  .article__table { font-size: 15px; }
  .article__table th,
  .article__table td { padding: 8px 6px; }
}

/* Article layout corrections.

   Measured at 1440px before the change: .article__inner sat at x=75 with
   545px of dead space down the right, because max-width: 760px had no auto
   margins. Every FAQ h3 had margin-top: 0 against h2's 46px, so questions
   ran into the answer above them. And the CTA button inherited body-link
   green from .article__inner a, putting #17703A text on a #209D50 fill,
   roughly 1.7:1 where 4.5:1 is the minimum. */
.article__inner { margin-left: auto; margin-right: auto; }

.article__inner h3 {
  font-size: 22px;
  line-height: 1.35;
  margin-top: 32px;
}

/* The button is an <a>, so it has to beat .article__inner a. */
.article__inner .thm-btn,
.article__inner .thm-btn:hover,
.article__inner .thm-btn:focus { color: #ffffff; }

/* Inline article images. */
.article__figure { margin: 34px 0; }
.article__figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 6px;
}
.article__figure figcaption {
  margin-top: 10px;
  font-size: 15px;
  line-height: 1.5;
  color: #6b736d;
}
@media (max-width: 575px) {
  .article__figure { margin: 26px 0; }
  .article__figure figcaption { font-size: 14px; }
}

/* Folding the closing CTA into the last section kept the page at 7 H2s,
   but it left the sign-off sitting inside "Common questions" where it read
   as one more answer. A rule above it ends the article instead. */
.article__close {
  margin-top: 40px;
  padding-top: 30px;
  border-top: 1px solid #e5e7eb;
}

/* Article sidebar.

   Measured at 1440px: the 760px text column left 280px empty on each side
   of a 1320px container. Widening the column was the wrong fix, because
   rendered line length already averages 67 characters, inside the 50 to 75
   band that reads best; filling the container would push it past 90.

   So the space carries a contents list, the sibling article and a quote
   prompt. 760 + 64 + 300 = 1124, which fills the container without
   touching the measure. */
.article__layout {
  display: grid;
  grid-template-columns: minmax(0, 760px) 300px;
  gap: 64px;
  justify-content: center;
}
.article__aside { height: 100%; }

/* The column centres itself when there is no sidebar; inside the grid the
   track already positions it. */
.article__layout .article__inner { margin-left: 0; margin-right: 0; }

.article__aside-inner {
  position: sticky;
  top: 110px;
}
.article__aside-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #6b736d;
  margin-bottom: 12px;
}
.article__toc {
  list-style: none;
  margin: 0 0 30px;
  padding: 0 0 0 14px;
  border-left: 2px solid #e5e7eb;
}
.article__toc li + li { margin-top: 10px; }
.article__toc a {
  font-size: 15px;
  line-height: 1.45;
  color: #3d4540;
  font-weight: 500;
  text-decoration: none;
}
.article__toc a:hover,
.article__toc a:focus { color: var(--brand-green-on-light); }

.article__aside-card {
  padding: 20px;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  margin-bottom: 18px;
}
.article__aside-card--cta { background: #f6f8f6; border-color: #dce5dd; }
.article__aside-link {
  display: block;
  font-size: 16px;
  line-height: 1.4;
  font-weight: 700;
  color: var(--color-heading);
  text-decoration: none;
}
.article__aside-link:hover,
.article__aside-link:focus { color: var(--brand-green-on-light); }
.article__aside-blurb {
  margin-top: 8px;
  font-size: 14px;
  line-height: 1.55;
  color: #6b736d;
}
.article__aside-btn {
  display: block;
  margin-top: 14px;
  padding: 13px 18px;
  font-size: 16px;
  text-align: center;
  color: #ffffff;
}
.article__aside-call {
  display: block;
  margin-top: 10px;
  font-size: 14px;
  text-align: center;
  color: var(--brand-green-on-light);
  font-weight: 600;
}

/* Anchor targets need to clear the sticky header. */
.article__inner h2 { scroll-margin-top: 110px; }

@media (max-width: 991px) {
  .article__layout { display: block; }
  .article__layout .article__inner { margin-left: auto; margin-right: auto; }
  /* The article reads linearly here and already carries its own CTA, so a
     duplicated sidebar would only add length. */
  .article__aside { display: none; }
}

/* Commercial page: the "straight answers" block.

   Measured at 1440px before this: two centred paragraphs running 100 and
   129 characters per line, against a readable band of 50 to 75, with the
   second one carrying four separate ideas at once. The lead is now capped
   to a sane measure and the four ideas are scannable items. */
.comm-lead {
  max-width: 760px;
  margin-left: auto;
  margin-right: auto;
}
.comm-points {
  list-style: none;
  margin: 42px auto 0;
  padding: 0;
  max-width: 1120px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 30px;
  text-align: left;
}
.comm-points li {
  padding-top: 18px;
  border-top: 2px solid rgba(255, 255, 255, 0.28);
}
.comm-points h3 {
  font-size: 18px;
  line-height: 1.3;
  color: #ffffff;
  margin-bottom: 8px;
}
.comm-points p {
  font-size: 16px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.82);
  margin: 0;
}
.comm-trust {
  margin: 38px auto 0;
  max-width: 760px;
  font-size: 15px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.72);
}
.project-bg .project-btn { margin-top: 30px; }

@media (max-width: 991px) {
  .comm-points { grid-template-columns: repeat(2, 1fr); gap: 26px; }
}
@media (max-width: 575px) {
  .comm-points { grid-template-columns: 1fr; gap: 22px; margin-top: 32px; }
  .comm-points h3 { font-size: 17px; }
  .comm-trust { margin-top: 30px; }
}

/* ===========================================================================
   Farm page corrections, part 1: colour and alignment
   Scoped to .power-solution, which is the farm page's body class.

   The page carried three dark bands (two pure black, one dark green), an
   acid green #3FCB74 card, black circular icons, black pill buttons and a
   #0a55c7 blue on the open FAQ item. None of black, acid green or that
   blue is in the brand palette.

   The two black sections are now light, so everything that was white for a
   black background is brought back to a readable dark colour here.
   =========================================================================== */

/* --- overview: was black ------------------------------------------------ */
.power-solution .overview .sec-title .title,
.power-solution .overview-bottom-item .xb-item--title {
  color: var(--color-heading, #0d0d0d);
}
.power-solution .overview-bottom-item .xb-item--content {
  color: #3d4540;
}
.power-solution .overview-bottom-item .xb-item--more-btn,
.power-solution .overview-bottom-item .xb-item--more-btn span {
  color: var(--brand-green-on-light, #17703A);
}
/* The card was --color-primary-two (#3FCB74). A light brand tint keeps the
   dark body copy on it readable, which the acid green did not. */
.power-solution .overview-item .xb-item--inner {
  background: #E9F4ED;
  border: 1px solid #D3E6D9;
}
.power-solution .overview-item .xb-item--inner .xb-item--title,
.power-solution .overview-item .xb-item--inner .xb-item--content {
  color: #0d0d0d;
}

/* --- faq: was black ----------------------------------------------------- */
.power-solution .faq .sec-title .title,
.power-solution .faq .sec-title p,
.power-solution .faq .sec-title .content {
  color: var(--color-heading, #0d0d0d);
}
.power-solution .faq .accordion_box .block .acc-btn,
.power-solution .faq .accordion_box .block .acc-btn * {
  color: var(--color-heading, #0d0d0d);
}
/* #0a55c7 appears nowhere else on the site. Brand dark green instead, which
   also gives white body copy about 9:1 rather than fighting the blue. */
.power-solution .ps-faq .accordion_box .block.active-block {
  background: #17532F;
}
.power-solution .ps-faq .accordion_box .block.active-block,
.power-solution .ps-faq .accordion_box .block.active-block * {
  color: #ffffff;
}

/* --- black pills and icons --------------------------------------------- */
.power-solution .power-btn--balck { color: #ffffff; }
.power-solution .ps-about-item .xb-item--icon { background: #17532F; }

/* --- project carousel: slides sat 35px left of the heading -------------- */
.power-solution .project .swiper,
.power-solution .project .swiper-container { overflow: visible; }
.power-solution .project .xb-carousel,
.power-solution .project .swiper-wrapper { margin-left: 0; }
.power-solution .project .swiper-slide { margin-left: 0; }

/* ===========================================================================
   Farm page corrections, part 2: layout
   =========================================================================== */

/* The intro now sits in the left column beside the photo rather than
   spanning the container above it. */
.power-solution .farm-lead {
  font-size: 18px;
  line-height: 1.7;
  color: #3d4540;
}
.power-solution .farm-lead + .farm-lead { margin-top: 14px; }
.power-solution .about-left-content .ps-about-item { margin-top: 34px; }

/* The photo should fill the column beside the text rather than float at
   its natural height. */
.power-solution .about-right-content .xb-img,
.power-solution .infographic-left-content .xb-img { height: 100%; }
.power-solution .about-right-content .xb-img img,
.power-solution .infographic-left-content .xb-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 8px;
}
.power-solution .infographic-left-content { display: block; }

@media (max-width: 991px) {
  /* Stacked, the photo should not take half the screen height. */
  .power-solution .about-right-content .xb-img img,
  .power-solution .infographic-left-content .xb-img img {
    height: auto;
    max-height: 420px;
  }
}

/* ===========================================================================
   Farm page corrections, part 3
   =========================================================================== */

/* .sec-title--three .title is white by default, because the template only
   used it on dark sections. The about section is light, so its new heading
   was white on #F3F4F5, about 1.1:1. */
.power-solution .about .sec-title .title { color: var(--color-heading, #0d0d0d); }

/* The carousel lives in .project-wrap, which sits OUTSIDE .container, so it
   ran full-bleed while the heading was inset by the container gutter: the
   slides started 35px left of the heading. Padding the slider by the same
   offset lines the first slide up with the heading while the row still
   bleeds off the right, which is what the design intends.
   1440px: (1440-1320)/2 + 15 = 75, which is where the h2 sits. */
.power-solution .project-wrap {
  /* Was bleeding off the right edge, which left the block lopsided:
     flush with the heading on the left, running under the viewport
     edge on the right. Constrained to the container width and centred
     so both edges line up with the rest of the page. overflow: hidden
     from the template still clips the row. */
  max-width: 1290px;
  margin-left: auto;
  margin-right: auto;
}
.power-solution .project-slider { margin-right: 0; padding-left: 0; }
.power-solution .project-slider { padding-left: 0; }
@media (max-width: 991px) {
  .power-solution .project-wrap { margin-left: 15px; }
}

/* rural-array-valley is a portrait frame, so at column width it ran 780px
   tall against a 450px text column and left a hole under the text. */
.power-solution .infographic-left-content .xb-img img {
  max-height: 520px;
  object-fit: cover;
  object-position: center 62%;
}
/* The two feature items now sit in their own row under the intro. */
.power-solution .farm-benefits { margin-top: 56px; }
.power-solution .farm-benefits .ps-about-item { margin-top: 0; }

/* The "Still have a question?" prompt shares the left column with the FAQ
   heading, so when the columns stack it landed above the questions. Order
   the three parts explicitly instead: heading, questions, prompt.

   display: contents on the column lifts its children into the row so they
   can be ordered, which also drops the column's 15px gutter, so the row's
   matching negative margin has to go with it. */
@media (max-width: 991px) {
  .faq-row {
    display: flex;
    flex-direction: column;
    margin-left: 0;
    margin-right: 0;
  }
  .faq-row > [class*="col-"] { width: 100%; max-width: 100%; padding-left: 0; padding-right: 0; }
  .faq-row > [class*="col-"]:first-child,
  .faq-row .xb-faq-left { display: contents; }
  .faq-row .xb-faq-left .sec-title { order: 1; }
  .faq-row > [class*="col-"]:last-child { order: 2; }
  .faq-row .xb-faq-left .xb-item--holder { order: 3; margin-top: 40px; }
}

/* The FAQ columns are col-lg-5 and col-lg-7, whose 15px paddings gave a
   24px gutter between the left-hand prompt and the first question.
   Measured identical on all three pages. Two unrelated blocks of text
   that close together read as one column that failed to wrap. */
@media (min-width: 992px) {
  .faq-row .xb-faq-left { padding-right: 50px; }
}

/* .infographic-right-content carries margin-left: 57px from the template,
   where it was the right-hand column. The text is the LEFT column now, so
   that margin just indented the paragraph 57px past its own heading:
   measured h2 at x=75 and the paragraph at x=132. */
.power-solution .infographic-right-content { margin-left: 0; }

/* Farm solar services cards. Replaces the old collage of mismatched
   tiles: four equal cards, each with the photograph of the thing it
   describes. */
.power-solution .farm-services-lead {
  font-size: 18px;
  line-height: 1.7;
  color: #3d4540;
  max-width: 760px;
}
.power-solution .farm-services {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 30px;
}
.power-solution .farm-service picture { display: block; }
.power-solution .farm-service img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 8px;
}
.power-solution .farm-service h3 {
  margin: 18px 0 8px;
  font-size: 20px;
  line-height: 1.3;
  color: var(--color-heading, #0d0d0d);
}
.power-solution .farm-service p {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
  color: #3d4540;
}
@media (max-width: 1199px) {
  .power-solution .farm-services { grid-template-columns: repeat(2, 1fr); gap: 34px 28px; }
}
@media (max-width: 575px) {
  .power-solution .farm-services { grid-template-columns: 1fr; gap: 30px; }
  .power-solution .farm-service h3 { font-size: 19px; }
}

/* Service-area band, on every service page.

   A compact version of the homepage's "Areas we cover": same four
   districts and eighteen suburbs, no map and no JS, because cloning the
   interactive one would have put 18.6KB of markup and a duplicated widget
   on four more pages. */
.svc-areas__lead {
  font-size: 18px;
  line-height: 1.7;
  color: #3d4540;
  max-width: 820px;
}
.svc-areas__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 30px;
}
.svc-area h3 {
  font-size: 18px;
  line-height: 1.3;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 2px solid #d8e2da;
  color: var(--color-heading, #0d0d0d);
}
.svc-area ul { list-style: none; margin: 0; padding: 0; }
.svc-area li {
  font-size: 16px;
  line-height: 1.75;
  color: #3d4540;
}
@media (max-width: 767px) {
  .svc-areas__grid { grid-template-columns: repeat(2, 1fr); gap: 26px 20px; }
  .svc-area h3 { font-size: 17px; }
  .svc-area li { font-size: 15px; }
}

/* The self-hosted hero clip covers exactly as the embed does. */
.hero-video video {
  /* The iframe next door needs max(100cqw, 177.78cqh) because an
     embed cannot crop itself, but that blew this element out to
     1470px wide on a 390px screen and threw away three quarters of
     the encoded pixels. A portrait file just covers the box. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 0;
}

/* One honest reference to the project, replacing a carousel whose three
   cards all linked to the same page. */
.power-solution .farm-services-note {
  margin-top: 34px;
  font-size: 17px;
  line-height: 1.7;
  color: #3d4540;
  max-width: 820px;
}
.power-solution .farm-services-note a { color: var(--brand-green-on-light, #17703A); font-weight: 600; }

/* Address autocomplete on the quote forms. Mirrors the roof check's list,
   but self-contained so these pages do not have to pull roof-check.css. */
.addr-field { position: relative; }
.addr-suggest {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 40;
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
  background: #ffffff;
  border: 1px solid #d8e2da;
  border-radius: 6px;
  box-shadow: 0 10px 28px rgba(13, 13, 13, 0.12);
  max-height: 272px;
  overflow-y: auto;
}
.addr-suggest__item {
  padding: 10px 14px;
  cursor: pointer;
  border-bottom: 1px solid #eef2ef;
  line-height: 1.35;
}
.addr-suggest__item:last-child { border-bottom: 0; }
.addr-suggest__item:hover,
.addr-suggest__item[aria-selected="true"] { background: #EAF6EE; }
.addr-suggest__main { display: block; font-size: 16px; color: var(--color-heading, #0d0d0d); }
.addr-suggest__sub { display: block; font-size: 13px; color: #6b736d; margin-top: 2px; }

/* ===========================================================================
   Brand accent set to #209D50

   --color-primary was already #209D50, but the accent people actually see,
   the highlighted word in every section heading, was #24572F from main.css
   (.sec-title .title span, 319 of them). Same for the "why choose us" icon
   chips. Both now the brand green.

   Deliberately NOT changed: --brand-green-on-light (#17703A), which colours
   in-body links. #209D50 measures 3.50:1 on white, which clears the 3:1 bar
   for large text like these headings but fails the 4.5:1 body-text bar.
   #17703A is 6.15:1. Links stay readable.

   The dark bands (#17532F) are backgrounds, not accents, and stay.
   =========================================================================== */
.sec-title .title span,
.sec-title--two .title span,
.sec-title--three .title span {
  color: #209D50;
}
.xb-wcu-item .xb-item--icon { background: #209D50; }

/* Partners: three per row on desktop rather than letting six wrap wherever
   the widths happen to land. Grid instead of flex-wrap so the split is
   exact, with the marks centred in their cell. */
@media (min-width: 992px) {
  .partners__logos {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    justify-items: center;
    align-items: center;
    gap: 44px 56px;
    /* 1fr across the full 1290px container put 430px between marks and
       the row read as six stranded logos. Capped and centred so the two
       rows group as one block. */
    max-width: 880px;
    margin-left: auto;
    margin-right: auto;
  }
}

/* ===========================================================================
   wcu-boxed: the six "why choose" points as boxes

   The lead paragraph sat at the very top of a two-line heading, both at the
   same y, so it floated unanchored against 144px of heading. Centring the
   row settles it.

   The points were bare text separated by hairline rules, padded
   30px 26px 4px 0, so they read as a list rather than a set. Now boxes in a
   lighter shade of the same green: a translucent white wash over #209D50,
   which also lifts contrast for the dark copy on it.
   =========================================================================== */
@media (min-width: 992px) {
  .xb-wcu-top .row { align-items: center; }
}
.xb-wcu-wrap [class*="col-"] { display: flex; }
.xb-wcu-wrap .xb-wcu-item {
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 10px;
  padding: 28px 26px 26px;
  width: 100%;
}
.xb-wcu-item .xb-item--icon { margin-bottom: 18px; }
.xb-wcu-item .xb-item--title { margin-bottom: 10px; }
.xb-wcu-item .xb-item--content { margin-bottom: 0; }
@media (max-width: 991px) {
  .xb-wcu-wrap .xb-wcu-item { padding: 24px 22px; }
}

/* The blanket "main h2 { margin-bottom: 18px !important }" above applies at
   every width, so .partners__title lost its 52px and the heading sat 18px
   off the logos, tighter than the 44px between the two logo rows. Matching
   the !important rather than loosening the blanket rule, which exists to
   hold heading-to-paragraph gaps everywhere else. */
.partners__title { margin-bottom: 52px !important; }
@media (max-width: 575px) {
  .partners__title { margin-bottom: 34px !important; }
}

/* about-heading-balance
   This heading is one line on a wide desktop but drops its last word onto a
   line of its own between roughly 1200px and 1365px, which is a common
   laptop width. Balancing the lines fixes it at every width instead of
   tuning the wording to one of them. Browsers without text-wrap: balance
   just wrap as they do now, so there is nothing to fall back to. */
.about .sec-title .title { text-wrap: balance; }

/* ===========================================================================
   Testimonials. Three real Google reviews, supplied in Alex's own client PDF.
   Cards rather than a carousel: there are only three, and a carousel would
   hide two of them behind an interaction nobody performs.
   =========================================================================== */
.tmnl-lede {
  color: rgba(255, 255, 255, 0.86);
  margin: 0;
}
.tmnl-grid {
  display: grid;
  gap: 26px;
  margin: 0;
  padding: 0;
}
@media (min-width: 992px) {
  .tmnl-grid { grid-template-columns: repeat(3, 1fr); }
}
.tmnl-item { display: flex; }
.tmnl-quote {
  position: relative;
  width: 100%;
  margin: 0;
  padding: 58px 30px 28px;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
}
/* The opening mark is decoration, so it is drawn rather than typed: a real
   character here would be read out by a screen reader before the quote. */
.tmnl-quote::before {
  content: "";
  position: absolute;
  top: 26px;
  left: 30px;
  width: 34px;
  height: 24px;
  background: var(--brand-green-on-dark, #4FD17E);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 34 24'%3E%3Cpath d='M0 24V13.2C0 5.9 4.6 1 12.2 0l1.4 4.3C9.3 5.4 7 7.7 6.8 11.2H13V24zm21 0V13.2C21 5.9 25.6 1 33.2 0l1.4 4.3c-4.3 1.1-6.6 3.4-6.8 6.9H34V24z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 34 24'%3E%3Cpath d='M0 24V13.2C0 5.9 4.6 1 12.2 0l1.4 4.3C9.3 5.4 7 7.7 6.8 11.2H13V24zm21 0V13.2C21 5.9 25.6 1 33.2 0l1.4 4.3c-4.3 1.1-6.6 3.4-6.8 6.9H34V24z'/%3E%3C/svg%3E") no-repeat center / contain;
}
.tmnl-quote p {
  color: #ffffff;
  font-size: 17px;
  line-height: 1.68;
  margin: 0 0 22px;
  flex: 1 1 auto;
}
.tmnl-by {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin-top: auto;
}
.tmnl-by cite {
  font-style: normal;
  font-weight: 600;
  font-size: 17px;
  color: var(--brand-green-on-dark, #4FD17E);
}
.tmnl-src {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.72);
}
@media (max-width: 575px) {
  .tmnl-quote { padding: 54px 24px 24px; }
  .tmnl-quote p { font-size: 16px; }
}

/* Captions under the "Other projects" thumbnails. Without these the three
   images at the foot of a project page are unlabelled links, which is what
   they were: same photo set on every page, all pointing back at the page
   you were already on. */
.project-details-img__cap {
  margin: 14px 0 2px;
  font-weight: 600;
  font-size: 19px;
  line-height: 1.35;
}
.project-details-img__cap { color: var(--color-heading, #0d0d0d); transition: color 0.2s ease; }
.project-details-img__sub {
  margin: 0;
  font-size: 15px;
  color: #5d6660;
}

/* The photo and the heading on the Recent work card are links too, not just
   the "Read the ... project" line. ".project-spec a" paints every anchor in
   the card green and underlined, which is right for the text link and wrong
   for a block wrapping an image, so both get their own rule.
   The image link is aria-hidden and out of the tab order: it goes to the
   same place as the heading link beside it, and a screen reader announcing
   the destination three times is noise. */
.project-spec__imglink {
  display: block;
  text-decoration: none;
}
.project-spec h3 .project-spec__titlelink {
  color: inherit;
  text-decoration: none;
}
.project-spec h3 .project-spec__titlelink:hover,
.project-spec h3 .project-spec__titlelink:focus-visible {
  color: var(--brand-green-on-light);
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* ===========================================================================
   Project carousel. Replaces the single pinned project in "Recent work" and
   on home solar. Swiper 6.7.0, already loaded on both pages.
   =========================================================================== */
.project-carousel { overflow: hidden; }
/* Equal-height slides: the cards carry different amounts of text and a
   carousel that changes height on every rotation is worse than a tall one. */
.project-carousel .swiper-wrapper { align-items: stretch; }
.project-carousel .swiper-slide { height: auto; display: flex; }
.project-carousel .project-spec {
  width: 100%;
  display: flex;
  flex-direction: column;
}
.project-carousel .project-spec__body { flex: 1 1 auto; display: flex; flex-direction: column; }
/* Push the "Read the ... project" link to the bottom so it lines up across
   slides regardless of how long the blurb is. */
.project-carousel .project-spec > .project-spec__body > a:last-child { margin-top: auto; }

.project-carousel__nav {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 22px;
}
.project-carousel__btn {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid #d3d7d4;
  border-radius: 50%;
  background: #ffffff;
  color: #0d0d0d;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}
.project-carousel__btn svg { width: 20px; height: 20px; display: block; }
.project-carousel__btn--prev svg { transform: rotate(180deg); }
.project-carousel__btn:hover,
.project-carousel__btn:focus-visible {
  background: #209D50;
  border-color: #209D50;
  color: #ffffff;
}
.project-carousel__btn[disabled] { opacity: .4; cursor: default; }
.project-carousel__btn[disabled]:hover {
  background: #ffffff; border-color: #d3d7d4; color: #0d0d0d;
}

.project-carousel__dots {
  display: flex;
  align-items: center;
  gap: 9px;
}
/* Swiper paints its own bullet styles inline-ish; these override without
   !important because the custom container class wins on specificity. */
.project-carousel__dots .swiper-pagination-bullet {
  width: 9px;
  height: 9px;
  margin: 0;
  border-radius: 50%;
  background: #c3c8c4;
  opacity: 1;
  transition: background .18s ease, width .18s ease;
}
.project-carousel__dots .swiper-pagination-bullet-active {
  background: #209D50;
  width: 26px;
  border-radius: 6px;
}
@media (max-width: 575px) {
  .project-carousel__nav { gap: 14px; margin-top: 18px; }
  .project-carousel__btn { width: 40px; height: 40px; }
}
