/* ==========================================================================
   Fernz Gas & Plumbing Specialist: shared stylesheet
   Built to 05_Design_System_Spec.md. Section numbers below match that doc.
   ========================================================================== */

/* ---------- 2. Color System ---------- */
:root {
  --blue: #267FC1;
  --blue-dark: #1D6299;
  --blue-tint: #5CA3D9;
  --blue-pale: #EAF3FB;

  --red: #E82D2B;
  --red-muted: #B8231F;
  --red-pale: #FBEAEA;

  --navy: #10365A;
  --navy-2: #1C4A73;

  --gold: #E8A93B;

  --text-body: #1c2b3a;
  --text-on-navy: #FFFFFF;
  --text-support-on-navy: #cfe0ee;
  --field-border: #e2e6ea;
  --field-border-focus: var(--blue);
  --error-text: var(--red-muted);

  /* 3. Spacing / grid / breakpoints */
  --space-4: 4px;
  --space-8: 8px;
  --space-12: 12px;
  --space-16: 16px;
  --space-24: 24px;
  --space-32: 32px;
  --space-48: 48px;
  --space-64: 64px;
  --space-96: 96px;

  --container-max: 1240px;
  --gutter-mobile: 20px;
  --gutter-desktop: 40px;

  /* 5. Elevation / shadow system */
  --shadow-card: 0 6px 20px rgba(16, 54, 90, 0.16);
  --shadow-top: 0 2px 14px rgba(16, 54, 90, 0.1);
  --shadow-bottom: 0 -4px 12px rgba(0, 0, 0, 0.28);
  --shadow-hover: 0 12px 28px rgba(16, 54, 90, 0.24);
  --shadow-soft: 0 2px 8px rgba(16, 54, 90, 0.08);
  --shadow-rate-card: 0 4px 12px rgba(16, 54, 90, 0.12);

  /* 4. Buttons */
  --radius-btn: 6px;
}

/* ---------- Reset / base ---------- */
* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: #ffffff;
  color: var(--text-body);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  -webkit-font-smoothing: antialiased;
  /* Deliberately NOT overflow-x:hidden here (or on html) - tried as a
     safety net for the hero-photo full-bleed overflow bug earlier this
     session (see git history, commits 48a8c38/b689665/9bbb8fb), but it
     breaks position:sticky sitewide (the header, both trust-strip
     variants): setting overflow-x to anything but visible forces
     overflow-y to compute as auto too per spec, turning html/body into
     an actual scroll container, which changes what "nearest scrolling
     ancestor" means for every sticky element on the page. Confirmed by
     Veeral losing sticky header/trust-strip immediately after this was
     added. Safe to remove now that .hero-photo's breakout is a fixed-
     gutter calc (see its own rule) instead of a vw-based one - the
     overflow this was guarding against no longer exists at the source,
     so the guard itself was doing more harm than good. If a future
     full-bleed element ever needs this kind of protection again, scope
     overflow-x:hidden to that element's own direct wrapper, not html/
     body. */
}

img {
  max-width: 100%;
  display: block;
}

a {
  color: var(--blue);
  text-decoration: none;
}

a:hover {
  color: var(--blue-dark);
}

/* One shared treatment for inline body-copy links that need to visually
   stand out as clickable (e.g. "Pricing page" references), rather than each
   spot inventing its own bold/underline combination. */
.link-strong {
  color: var(--blue);
  font-weight: 700;
  text-decoration: underline;
}

.container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding-left: var(--gutter-mobile);
  padding-right: var(--gutter-mobile);
}

@media (min-width: 1024px) {
  .container {
    padding-left: var(--gutter-desktop);
    padding-right: var(--gutter-desktop);
  }
}

/* ---------- 1. Typography ---------- */
h1, h2, h3,
.h1, .h2, .h3 {
  font-family: 'Schibsted Grotesk', 'Inter', sans-serif;
  color: var(--navy);
  margin: 0;
}

h1, .h1 {
  font-size: 28px;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.5px;
}

h2, .h2 {
  font-size: 24px;
  font-weight: 700;
  line-height: 1.15;
}

h3, .h3 {
  font-size: 20px;
  font-weight: 700;
  line-height: 1.2;
}

@media (min-width: 1024px) {
  h1, .h1 { font-size: 40px; }
  h2, .h2 { font-size: 30px; }
  h3, .h3 { font-size: 22px; }
  p, li { font-size: 18px; }
}

p, li {
  font-family: 'Inter', sans-serif;
  font-weight: 400;
  font-size: 17px;
  line-height: 1.65;
  max-width: 65ch;
  margin: 0 0 var(--space-16);
}

.small, .proof-line, .caption {
  font-family: 'Inter', sans-serif;
  font-weight: 500;
  font-size: 14px;
  line-height: 1.5;
}

.nav-link {
  font-family: 'Inter', sans-serif;
  font-weight: 500;
  font-size: 15px;
}

.header-business-name {
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 17px;
}

/* ---------- 4. Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 15.5px;
  letter-spacing: 0.2px;
  padding: 13px 26px;
  border-radius: var(--radius-btn);
  border: none;
  cursor: pointer;
  text-align: center;
  transition: background-color 150ms ease, border-color 150ms ease, transform 100ms ease;
}

.btn-primary {
  background: var(--red);
  color: #ffffff;
}

.btn-primary:hover {
  background: var(--red-muted);
  color: #ffffff;
}

.btn-primary:active {
  transform: scale(0.97);
}

.btn-secondary {
  background: var(--blue-pale);
  color: var(--blue-dark);
  border: 1px solid var(--blue-tint);
}

.btn-secondary:hover {
  background: var(--blue-tint);
  border-color: var(--blue-dark);
  color: var(--blue-dark);
}

.btn-secondary:active {
  transform: scale(0.97);
}

/* Scoped to the Home "What We Do" CTA specifically (.btn-secondary is shared
   with the 404 page's "See services" button, which keeps its existing hover
   as-is). */
.wwd-cta .btn-secondary:hover {
  background: var(--navy);
  border-color: var(--navy);
  color: #fff;
}

.btn:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 2px;
}

/* ---------- Form fields ---------- */
input, textarea, select {
  font-family: 'Inter', sans-serif;
  font-size: 15px;
  padding: 12px 14px;
  border-radius: 6px;
  border: 1px solid var(--field-border);
  width: 100%;
  color: var(--text-body);
}

input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--field-border-focus);
  box-shadow: 0 0 0 1px var(--blue);
}

label {
  font-family: 'Inter', sans-serif;
  font-weight: 500;
  font-size: 14px;
  color: var(--navy);
  display: block;
  margin-bottom: var(--space-8);
}

/* ---------- 6. Motion ---------- */
.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 500ms ease-out, transform 500ms ease-out;
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    transition: none;
  }
  html {
    scroll-behavior: auto;
  }
}

/* ---------- 7. Header & Navigation ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: #ffffff;
  box-shadow: var(--shadow-top);
  height: 72px;
}

.site-header .container {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-16);
}

.logo-lockup {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  color: var(--navy);
}

.logo-lockup img {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
}

/* Business name (header + footer instances): "Fernz Gas & Plumbing" (nbsp-joined,
   never wraps internally) followed by a "Specialist" span. On mobile that span stays
   inline, so the whole name reads as one line. At 768px+ it switches to display:block,
   which starts it on its own line — giving a clean, deliberate 2-line break instead of
   relying on a <br> (avoids stray-whitespace edge cases when toggling per breakpoint).
   max-width: none on both scoped selectors below cancels the older, unscoped
   .header-business-name max-width rules further down this file (105px/112px, sized
   for the name before "Specialist" was appended) — those are both flex items
   (blockified children of .logo-lockup/.footer-logo, both display:flex), so a leftover
   max-width there would still apply and force line 1 to overflow its box instead of
   sitting at its natural width. */
.site-header .header-business-name,
.footer-logo .header-business-name {
  max-width: none;
  white-space: normal;
  line-height: 1.15;
}

.biz-name-l2 {
  display: inline;
}

/* Header always wraps to 2 lines, including mobile — higher specificity than the
   generic .biz-name-l2 rule above beats it at every width, no media query needed.
   Footer keeps the generic rule as-is (1 line on mobile, 2 lines at 768px+). */
.site-header .biz-name-l2 {
  display: block;
}

@media (min-width: 768px) {
  .biz-name-l2 {
    display: block;
  }
}

.desktop-nav {
  display: none;
  align-items: center;
  gap: 26px;
  height: 100%;
}

.desktop-nav a {
  color: var(--navy);
  position: relative;
  display: flex;
  align-items: center;
  height: 60px;
  padding: 0 14px;
  border-radius: 6px 6px 0 0;
}

.desktop-nav a[aria-current="page"] {
  background: var(--blue-pale);
  color: var(--blue-dark);
  font-weight: 600;
  border-bottom: 3px solid var(--red);
}

.header-cta {
  display: none;
  align-items: center;
  gap: var(--space-16);
}

.header-phone {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  color: var(--navy);
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 15px;
}

.phone-copy {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  position: relative;
}

.header-phone-icon {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  color: var(--blue);
}

.btn-header {
  padding: 10px 20px;
  font-size: 14px;
}

.copy-btn {
  background: none;
  border: none;
  cursor: pointer;
  opacity: 0;
  transition: opacity 150ms ease;
  color: var(--blue);
  padding: 4px;
  display: inline-flex;
  align-items: center;
}

.phone-copy:hover .copy-btn {
  opacity: 1;
}

.copy-btn svg {
  width: 16px;
  height: 16px;
}

.copy-icon-check {
  display: none;
}

.copy-btn.is-copied .copy-icon-default {
  display: none;
}

.copy-btn.is-copied .copy-icon-check {
  display: inline-flex;
}

.copy-tooltip {
  position: absolute;
  top: -28px;
  right: 0;
  background: var(--blue);
  color: #fff;
  font-size: 12px;
  font-weight: 500;
  padding: 4px 9px;
  border-radius: 6px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 150ms ease;
  white-space: nowrap;
}

.copy-btn:hover + .copy-tooltip {
  opacity: 1;
}

/* Open horizontal space (not a nav bar / tight row): tooltip sits to the right instead of above */
.hero-phone-secondary .copy-tooltip,
.footer-phone-wrap .copy-tooltip,
.terms-payment-copy-wrap .copy-tooltip {
  top: 50%;
  right: auto;
  left: calc(100% + 8px);
  transform: translateY(-50%);
}

/* Dark/navy surface (footer): flip tooltip + checkmark to stay high-contrast */
.footer-phone-wrap .copy-tooltip {
  background: #fff;
  color: var(--blue);
}

.footer-phone-wrap .copy-icon-check {
  color: #fff;
}

/* Mobile hamburger */
.mobile-hamburger {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  margin-right: 6px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}

@media (min-width: 768px) {
  .desktop-nav {
    display: flex;
  }
  .desktop-nav a {
    white-space: nowrap;
  }
  .header-cta {
    display: flex;
  }
  .header-phone a,
  .btn-header {
    white-space: nowrap;
  }
  .mobile-hamburger {
    display: none;
  }
}

/* Tablet tier (both orientations, up to iPad Pro 11" landscape at
   1194px): swap to the same simple hamburger nav mobile uses instead of
   cramming every page link into a compacted inline row. Overrides the
   min-width:768px rule above for just this sub-range - true desktop
   (1195px+) is untouched since it falls outside this query. */
@media (min-width: 768px) and (max-width: 1194.98px) {
  .desktop-nav,
  .header-cta {
    display: none;
  }
  .mobile-hamburger {
    display: flex;
  }
  .mobile-drawer {
    display: flex;
  }
}

@media (min-width: 1024px) {
  .header-business-name {
    max-width: 112px;
    white-space: normal;
    line-height: 1.15;
  }
}

.mobile-hamburger .bar {
  width: 24px;
  height: 2px;
  background: var(--navy);
  border-radius: 1px;
  transition: transform 220ms ease, opacity 220ms ease;
}

.mobile-hamburger[aria-expanded="true"] .bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.mobile-hamburger[aria-expanded="true"] .bar:nth-child(2) {
  opacity: 0;
  transform: scaleX(0);
}
.mobile-hamburger[aria-expanded="true"] .bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* Mobile menu drawer */
.mobile-drawer {
  position: fixed;
  top: 72px;
  left: 0;
  right: 0;
  height: calc(100svh - 72px);
  background: var(--navy-2);
  z-index: 99;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--space-16) var(--gutter-mobile);
  padding-bottom: calc(var(--space-16) + env(safe-area-inset-bottom));
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
  transition: opacity 200ms ease, transform 200ms ease;
}

.mobile-drawer.is-open {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
  .mobile-drawer {
    transition-duration: 1ms;
  }
  .mobile-hamburger .bar {
    transition-duration: 1ms;
  }
}

.mobile-drawer-links {
  display: flex;
  flex-direction: column;
}

.mobile-drawer-links a {
  color: #fff;
  font-family: 'Inter', sans-serif;
  font-weight: 500;
  font-size: 19px;
  padding: 14px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 0 6px 6px 0;
}

.mobile-drawer-links a[aria-current="page"] {
  font-weight: 600;
  border-left: 3px solid var(--red);
  background: rgba(255, 255, 255, 0.08);
  padding-left: 9px;
}

.mobile-drawer-bottom {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
}

.drawer-phone-btn {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 15px;
  border-radius: 6px;
  padding: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
}

.drawer-phone-btn svg {
  width: 18px;
  height: 18px;
}

@media (min-width: 768px) {
  .mobile-drawer {
    display: none;
  }
}

/* ---------- 8. Sticky Mobile Call Bar ---------- */
.call-bar {
  position: sticky;
  bottom: 0;
  z-index: 90;
  background: var(--red);
  color: #fff;
  box-shadow: var(--shadow-bottom);
}

.call-bar a {
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  min-height: 48px;
  padding: var(--space-12) var(--gutter-mobile);
  padding-bottom: calc(var(--space-12) + env(safe-area-inset-bottom));
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 15.5px;
}

.call-bar svg {
  width: 18px;
  height: 18px;
}

@media (min-width: 768px) {
  .call-bar {
    display: none;
  }
}

/* ---------- 15. Footer ---------- */
.site-footer {
  background: var(--navy-2);
  color: #fff;
  padding: var(--space-64) 0 0;
}

.site-footer a {
  color: #fff;
}

.site-footer a:hover {
  color: var(--blue-tint);
}

.footer-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-32);
}

/* Tablet (both orientations, up to 1194.98px): footer's own .container
   instances (.footer-grid and .footer-bottom, both siblings sharing the
   class) were still stuck at the mobile 20px gutter here since the
   sitewide desktop-gutter switch doesn't land until 1024px - left the
   copyright/credit row on .footer-bottom (justify-content:space-between,
   stretched to the container's own edges) sitting close to the screen
   edge on tablet portrait. Scoped to the footer only, not the sitewide
   .container. */
@media (min-width: 768px) and (max-width: 1194.98px) {
  .site-footer .container {
    padding-left: var(--gutter-desktop);
    padding-right: var(--gutter-desktop);
  }
}

@media (min-width: 768px) {
  .footer-grid {
    grid-template-columns: 1.3fr 0.8fr 1fr 1fr;
    gap: var(--space-24);
  }
}

.footer-brand {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
}

.footer-logo {
  display: flex;
  align-items: center;
  gap: 10px;
}

.footer-logo img {
  width: 30px;
  height: 30px;
}

.footer-logo .header-business-name {
  color: #fff;
}

.footer-tagline {
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-support-on-navy);
  margin: 0;
  max-width: 30ch;
}

.footer-credential {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-size: 14px;
  color: var(--text-support-on-navy);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: var(--radius-btn);
  padding: 6px 10px;
  width: fit-content;
}

.footer-credential strong {
  color: #fff;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.footer-heading {
  font-family: 'Schibsted Grotesk', sans-serif;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--blue-tint);
  margin: 0 0 var(--space-16);
}

.footer-nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  font-size: 14.5px;
}

.footer-phone-wrap {
  margin-bottom: var(--space-16);
}

.footer-phone-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 15px;
  border-radius: var(--radius-btn);
  padding: 10px 14px;
}

.footer-phone-btn:hover {
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
}

.footer-phone-btn svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.footer-phone-sub {
  font-size: 14px;
  color: var(--text-support-on-navy);
  margin: 0 0 var(--space-16);
}

.footer-contact-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14.5px;
  margin-bottom: var(--space-12);
  line-height: 1.5;
}

.footer-contact-item:last-child {
  margin-bottom: 0;
}

.footer-contact-item svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--blue-tint);
}

.footer-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 var(--space-12);
}

.footer-chip {
  font-size: 14px;
  font-weight: 600;
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: #fff;
}

.footer-area-note {
  font-size: 14px;
  color: var(--text-support-on-navy);
  margin: 0;
  line-height: 1.5;
}

.footer-bottom {
  margin-top: var(--space-48);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  padding: var(--space-16) 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  align-items: center;
  text-align: center;
}

@media (min-width: 640px) {
  .footer-bottom {
    flex-direction: row;
    justify-content: space-between;
    text-align: left;
  }
}

.footer-copyright {
  font-size: 14px;
  color: #9fb6cc;
  margin: 0;
}

.footer-terms-btn {
  display: inline-flex;
  align-items: center;
  margin-left: 8px;
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  font-size: 12.5px;
  color: #d7e0e9;
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: var(--radius-btn);
  padding: 3px 10px;
  text-decoration: none;
  transition: background 150ms ease, border-color 150ms ease, color 150ms ease;
}

.footer-terms-btn:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.6);
  color: #fff;
}

.footer-credit {
  font-size: 14px;
  color: #8098af;
  margin: 0;
}

.footer-credit a {
  color: #a9c1d6;
  font-weight: 600;
}

.footer-credit a:hover {
  color: var(--blue-tint);
  text-decoration: underline;
}

/* ---------- Hero ---------- */
.hero {
  background: var(--navy);
  padding: var(--space-48) 0 var(--space-64);
}

@media (max-width: 767.98px) {
  .hero {
    padding-top: var(--space-48);
  }
}

.hero .container {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-32);
}

.hero-text {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.hero-text h1 {
  color: #fff;
}

.hero-tag {
  display: block;
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 500;
  color: var(--blue-tint);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin-bottom: 4px;
}

.hero-headline {
  display: block;
  /* Fluid across the full viewport range rather than a fixed jump at
     1024px - grows on large monitors instead of capping at desktop
     size. Upper bound is NOT 96px as first tried: font-size scales with
     viewport width (vw), but the hero column itself is capped by
     --container-max (1240px) and stops growing well before the
     viewport does, so a large-enough vw-based size eventually exceeds
     the column and wraps to two lines. Measured live at a 2560px-wide
     (27"+ monitor) viewport where the column is 620px: 88px still fits
     "Gas Specialist" on one line, 92px wraps. 80px keeps real margin
     below that hard limit while still reading as a deliberate, larger
     headline rather than the original fixed 60px. */
  font-size: clamp(40px, 4.2vw, 80px);
  font-weight: 700;
  line-height: 1.05;
  margin-bottom: 4px;
}

.hero-subline {
  display: block;
  font-family: 'Inter', sans-serif;
  font-size: 19px;
  font-weight: 500;
  letter-spacing: normal;
  color: var(--text-support-on-navy);
}

@media (min-width: 1024px) {
  .hero-tag {
    font-size: 17px;
  }

  .hero-subline {
    font-size: 25px;
  }

  .hero-support {
    font-size: 17px;
  }
}

.hero-support {
  color: var(--text-support-on-navy);
  font-size: 16px;
  margin-top: var(--space-12);
}

.hero-support + .hero-support {
  margin-top: 4px;
}

.hero-badges {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 14px;
}

.hero-badges + .hero-microtrust {
  margin-top: 0;
}

@media (max-width: 767.98px) {
  .hero-badges {
    margin-top: var(--space-16);
    margin-bottom: var(--space-24);
  }
}

.hero-badge {
  display: flex;
  align-items: center;
  gap: 11px;
  background: rgba(255, 255, 255, 0.06);
  border: 0.5px solid rgba(255, 255, 255, 0.18);
  border-radius: 8px;
  padding: 10px 16px;
}

.hero-badge-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  flex-shrink: 0;
}

.hero-badge-icon svg {
  width: 20px;
  height: 20px;
}

.hero-badge-icon.is-red {
  background: var(--red);
}

.hero-badge-icon.is-blue {
  background: var(--blue);
}

.hero-badge-label {
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  line-height: 1.25;
  text-align: left;
}

@media (min-width: 1024px) {
  .hero-badges {
    gap: 14px;
    margin-bottom: 16px;
  }

  .hero-badge {
    padding: 12px 28px;
  }

  .hero-badge-icon {
    width: 38px;
    height: 38px;
  }

  .hero-badge-icon svg {
    width: 20px;
    height: 20px;
  }

  .hero-badge-label {
    font-size: 16px;
  }
}

/* Sized by a fluid width clamp, at the source file's true natural aspect
   ratio, at every viewport - no object-fit/object-position, no cropping,
   ever. Same rule applies on mobile through large desktop; only the
   rendered size changes. The source file itself is framed to include
   the full van (front bumper to rear, full roof-rack overhang) and the
   complete "FERNZ / GAS & PLUMBING SPECIALIST" text with nothing cut
   off, so "never crop" holds regardless of how this box gets sized. */
.hero-photo {
  margin-top: var(--space-16);
  width: clamp(240px, 32vw, 620px);
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.15);
}

@media (max-width: 767.98px) {
  .hero-photo {
    /* True full-bleed: escapes .container's gutter padding entirely so
       the image reaches the actual screen edges, no navy visible on
       either side. Square corners to match (rounded corners on a
       full-bleed edge would show a sliver of navy peeking through at
       each corner).

       Third technique tried for this breakout, both prior ones broke on
       a real device even after being verified in Chrome/Blink emulation
       (see git history): position:relative+left:50%+margin-left:-50vw
       first (broke immediately, wrong containing block for a flex
       item), then width:100vw+margin:calc(50%-50vw) (verified clean in
       Blink, still overflowed by a hair on real iPhone Safari, which
       responded by zooming the whole page out - the html/body
       overflow-x:hidden added for that is kept as a safety net but
       wasn't the real fix). Both of those depend on vw matching the
       true rendered viewport width exactly, which apparently isn't
       reliable across engines/devices for this nested case.

       This version needs no viewport unit and no assumption about
       .hero-text's on-screen position at all: .hero-photo's immediate
       containing block (.hero-text) has zero padding of its own - the
       only inset between it and the true edge of .hero (which has zero
       horizontal padding, confirmed in its own rule above) is
       .container's fixed --gutter-mobile. So the exact pixel amount to
       cancel is already a known constant, not something to derive from
       the viewport - width:100%+gutter each side, negative-margin
       exactly one gutter each side. Same fixed-pixel logic works
       identically on every engine, since it's not sensitive to vw
       rounding at all. */
    width: calc(100% + 2 * var(--gutter-mobile));
    margin-left: calc(-1 * var(--gutter-mobile));
    margin-right: calc(-1 * var(--gutter-mobile));
    margin-top: var(--space-24);
    border-radius: 0;
    border-left: none;
    border-right: none;
  }
}

.hero-photo img {
  display: block;
  width: 100%;
  height: auto;
}

.quick-facts {
  margin-top: var(--space-24);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.quick-fact {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-16);
  background: #fff;
  border-radius: 12px;
  padding: 14px 16px;
  box-shadow: var(--shadow-card);
}

.quick-fact-action {
  background: var(--blue-pale);
  border: 3px solid var(--blue);
  transition: background-color 220ms ease, transform 200ms ease-out, box-shadow 200ms ease-out;
}

.quick-fact-action .quick-fact-icon,
.quick-fact-action .quick-fact-icon svg,
.quick-fact-action .quick-fact-label,
.quick-fact-action .quick-fact-value,
.quick-fact-action .copy-btn {
  transition: background-color 220ms ease, color 220ms ease, stroke 220ms ease;
}

.quick-fact-action .quick-fact-icon {
  background: #fff;
  border: 2px solid var(--blue);
}

.quick-fact-tap-link {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}

.quick-fact-chevron {
  width: 18px;
  height: 18px;
  stroke: var(--blue-dark);
  flex-shrink: 0;
  margin-left: auto;
}

.quick-fact-copy-wrap {
  display: none;
  position: relative;
  z-index: 2;
  margin-left: var(--space-8);
  vertical-align: middle;
  align-items: center;
}

.quick-fact-copy-wrap .copy-btn {
  opacity: 1;
  padding: 6px;
}

.quick-fact-copy-wrap .copy-btn svg {
  width: 22px;
  height: 22px;
}

.quick-fact-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: #F6E2B3;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.quick-fact-icon svg {
  width: 20px;
  height: 20px;
  stroke: var(--navy);
}

.quick-fact-label {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--blue-dark);
  text-align: left;
}

.quick-fact-value {
  font-size: 18px;
  font-weight: 600;
  color: var(--navy);
  margin-top: 4px;
  line-height: 1.3;
  max-width: none;
  text-align: left;
}

.quick-fact-hours-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 4px;
}

.quick-fact-hours-time {
  font-size: 20px;
  font-weight: 600;
  color: var(--navy);
}

.quick-fact-hours-days {
  font-size: 14px;
  font-weight: 500;
  color: var(--blue-dark);
}

.quick-fact-hours-emergency {
  margin-top: 4px;
  font-size: 13px;
  color: #64748b;
  text-align: left;
}

.quick-fact-area-wider {
  margin-top: 3px;
  font-size: 15px;
  font-weight: 500;
  color: var(--blue-dark);
  text-align: left;
}

@media (min-width: 1024px) {
  .quick-facts {
    gap: var(--space-16);
  }

  .quick-fact {
    padding: 18px 20px;
  }

  .quick-fact-icon {
    width: 52px;
    height: 52px;
    border-radius: 12px;
  }

  .quick-fact-icon svg {
    width: 26px;
    height: 26px;
  }

  .quick-fact-chevron {
    display: none;
  }

  .quick-fact-copy-wrap {
    display: inline-flex;
  }

  .quick-fact-action:hover {
    background: var(--blue);
    transform: translateY(-4px);
    box-shadow: var(--shadow-hover);
  }

  .quick-fact-action:hover .quick-fact-icon {
    background: #fff;
  }

  .quick-fact-action:hover .quick-fact-icon svg {
    stroke: var(--navy);
  }

  .quick-fact-action:hover .quick-fact-label {
    color: #fff;
  }

  .quick-fact-action:hover .quick-fact-value {
    color: #fff;
  }

  .quick-fact-action:hover .copy-btn {
    color: #fff;
  }

  /* Card itself goes solid blue on hover - flip the tooltip/checkmark to the
     dark-surface variant too, otherwise a blue tooltip disappears against it */
  .quick-fact-action:hover .copy-tooltip {
    background: #fff;
    color: var(--blue);
  }
}

.hero-form-wrap {
  background: #fff;
  border-radius: 10px;
  padding: var(--space-24) var(--space-24) 10px;
  box-shadow: var(--shadow-card);
}

.hero-phone-secondary {
  margin: 0 auto;
  text-align: center;
  font-size: 15px;
  color: var(--text-body);
}

.form-hours-line {
  margin: 4px auto 0;
  text-align: center;
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 13px;
  color: var(--navy);
}

/* ---------- CTA trust rail (bottom-of-page form sections) ---------- */
/* Two .trust-signal badges (same component as the Services page trust
   badges) side by side, spacing handled by the wrapper's own gap. */
.cta-trust-rail {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-12);
  max-width: 560px;
  margin: 0 auto 20px;
}

.cta-trust-rail .trust-signal {
  margin-top: 0;
}

@media (min-width: 1024px) {
  .hero .container {
    grid-template-columns: 1fr 1fr;
    /* The form card is the hero's height floor (its natural content
       height is never compressed) - the photo column just centers
       against whatever that ends up being, columns are allowed to
       differ in height. */
    align-items: center;
    gap: var(--space-64);
  }
}

/* ---------- Trust strip visibility, tiered by viewport HEIGHT ----------
   Desktop/laptop widths only - mobile is untouched (see Rule 1 above for
   its one change). Two tiers, both driven by hero padding, not by
   touching the form or trust strip themselves (both are height floors,
   never compressed):
   - Large desktop (1000px+ viewport height): hero gets generous padding
     (flex-grow filling near-full viewport height) so the trust strip is
     fully visible on load with a small peek of "What We Do" below it.
   - Laptop/short-desktop (<1000px height): the form card's own natural
     height (measured live at ~650px) plus the header (72px) already
     leaves little headroom at this range, so hero padding is trimmed
     instead of grown - reclaims enough space that the trust strip is
     mostly visible (a majority of its height) rather than entirely
     below the fold, without ever touching the form/photo/headline
     themselves. A partial peek at its bottom edge is expected here,
     not a bug - forcing it fully on-screen at this height would mean
     shrinking real content, which Rules 1/2 forbid. */
@media (min-width: 1024px) and (max-height: 999.98px) {
  .hero {
    padding-top: var(--space-8);
    padding-bottom: var(--space-8);
  }
  /* 13 Aug 2026: this is the only breakpoint combo where the hero text can
     end up flush against the header (8px section padding, and the shrunk
     form column no longer keeps hero-text vertically centered away from
     the top - see main.js's short-viewport form scaleY). Fixed with a
     14px floor added directly to the tag, not to .hero's own padding, so
     it touches only where the text starts and never shifts
     #hero-form-panel's position - every other breakpoint already clears
     14px via .hero's own padding and needs no change. */
  .hero-tag {
    padding-top: 14px;
  }
}

/* Form footprint (tablet + laptop): CSS zoom scales the whole card -
   Tally iframe included - as one unit, width and height together,
   rather than just narrowing it. Confirmed trade-off: text/fields
   inside get visually smaller too, since Tally's own internal layout
   isn't reachable from this repo - zoom is the only lever that shrinks
   the actual footprint rather than just the padding around it.
   zoom alone only shrinks the rendered content/height - the box's own
   width still resolves to 100% of its column BEFORE zoom applies (measured
   live: zoom 0.65 shrank height but width stayed exactly full), so an
   explicit width percentage is needed too to actually shrink the
   footprint on both axes, centered via margin auto. */
@media (min-width: 768px) and (max-width: 1023.98px) {
  /* #hero-form-panel's own width/zoom shrink removed (tablet nav/form
     rework) - it now behaves like .hero-form-wrap does everywhere else
     on the site: natural full width within its column, no forced
     zoom. This was the cause of the tablet hero form rendering as a
     small, oddly-narrow floating card. */
  .hero-photo {
    /* True full-bleed, same fixed-gutter formula as mobile (see the
       comment there for why this replaced the earlier vw-based
       versions). .container's padding is still --gutter-mobile at this
       width - the desktop gutter only kicks in at 1024px+. */
    width: calc(100% + 2 * var(--gutter-mobile));
    margin-left: calc(-1 * var(--gutter-mobile));
    margin-right: calc(-1 * var(--gutter-mobile));
    border-radius: 0;
    border-left: none;
    border-right: none;
    box-shadow: 0 -6px 14px rgba(0, 0, 0, 0.22), 0 6px 14px rgba(0, 0, 0, 0.22);
  }
}

/* Reverted back to min-width:1024px (was briefly raised to 1195px to
   exclude iPad Pro 11" landscape from this short-viewport shrink, but
   that also stripped real laptop windows in the 1024-1194px range of
   the same protection - this rule prevents the form/button from
   overflowing a short viewport, which is a laptop-window-height problem
   as much as a tablet one, not something that should have moved with
   the tablet/laptop width boundary). Tablet landscape overlapping this
   range again is an accepted trade-off, same as elsewhere in this file -
   there's no way to distinguish the two by width alone. */
/* zoom replaced with transform:scaleY (12 Aug 2026) - zoom on a
   cross-origin iframe (the Tally embed) doesn't proportionally shrink
   its CONTENT, only the outer box: the iframe's internal document still
   renders at native, unscaled size and gets cropped to whatever window
   the smaller box leaves. A smaller zoom value crops away MORE content,
   not less - confirmed by testing 0.68, which cut the form off earlier
   than 0.85 did. transform is a pure post-render visual scale that can
   never crop iframe content (it doesn't affect how the iframe lays out
   its own document), so it's used here instead. .js-form-shrink is
   toggled by main.js, which also sets #hero-form-panel's own height
   explicitly to match the scaled size, since transform doesn't shrink
   the layout space it reserves on its own. */
@media (min-width: 1024px) and (max-height: 999.98px) {
  #hero-form-panel {
    width: 85%;
    margin: 0 auto;
    overflow: hidden;
  }
  #hero-form-panel .hero-form-inner.js-form-shrink {
    transform: scaleY(0.85);
    transform-origin: top;
  }
}

/* Tablet (768-1023px width, still single-column: photo/text block stacks
   directly above the form rather than beside it, so there's no laptop-
   tier equivalent free lunch - the two blocks' heights add together
   instead of just taking the max of the two). Same padding-trim lever
   as the laptop tier, plus trimming the stack's internal gaps, to get
   as close to "majority visible" as physically possible without
   touching the protected photo/headline (the form's footprint is
   reduced above instead, via zoom, since it's no longer fully
   protected the way it was before that was confirmed acceptable). */
@media (min-width: 768px) and (max-width: 1023.98px) and (max-height: 1100px) {
  .hero {
    padding-top: var(--space-16);
    padding-bottom: var(--space-16);
  }
  .hero .container {
    gap: var(--space-16);
  }
  .hero-support {
    margin-top: var(--space-8);
  }
  .hero-badges {
    margin-bottom: var(--space-8);
  }
  .hero-photo {
    margin-top: var(--space-8);
  }
}

@media (min-width: 1024px) and (min-height: 1000px) {
  /* min-height below is only a FLOOR - it cannot force hero-a shorter
     than its own natural content (dominated by the form's ~646px
     natural height). At a 1024px-tall viewport that natural stack
     (header + hero padding + form + trust strip) already leaves very
     little room to peek "What We Do" in below the trust strip, so the
     padding itself has to shrink too - the min-height calc alone can't
     get there, confirmed by measuring hero-system's actual rendered
     height exceeding its own calc() target live. */
  .hero {
    /* 22px = the previous 8px + a 14px increase, so the hero's own
       content is taller and pushes the trust strip further down,
       leaving less (ideally none) of "What We Do" peeking in below it
       on tall laptop viewports. */
    padding-top: 22px;
    padding-bottom: 22px;
  }

  .hero-system {
    display: flex;
    flex-direction: column;
    /* 100svh minus the sticky header's own height (72px, same constant
       used elsewhere in this file for viewport-height calculations) -
       still useful as a floor on very tall screens, where natural
       content (now shorter thanks to the reduced padding above) no
       longer fills the viewport on its own and flex-grow needs
       something to grow toward. */
    min-height: calc(100svh - 72px - 170px);
  }

  .hero-a {
    flex: 1 0 auto;
    display: flex;
    align-items: center;
  }

  .trust-strip {
    flex-shrink: 0;
  }
}

/* ---------- Mobile hero CTA + expandable form panel (<768px only) ---------- */
.hero-microtrust {
  font-size: 14px;
  font-weight: 500;
  text-align: center;
  color: rgba(255, 255, 255, 0.85);
  margin-top: var(--space-12);
  margin-bottom: var(--space-12);
}

.hero-microtrust .accent {
  font-weight: 700;
  color: #fff;
  border-bottom: 2px solid var(--red);
  padding-bottom: 1px;
}

.hero-microtrust + .hero-cta-btn {
  margin-top: 0;
}

.hero-cta-btn {
  display: block;
  width: 100%;
  text-align: center;
  margin-top: var(--space-32);
}

#hero-form-panel {
  max-height: 0;
  padding: 0;
  overflow: hidden;
  transition: max-height 300ms ease, padding 300ms ease;
  /* Header is sticky at 72px (see .site-header) - without this, the
     mobile CTA's scrollIntoView() would land the panel's top edge
     directly under the header with no breathing room. */
  scroll-margin-top: 88px;
}

#hero-form-panel.is-open {
  max-height: 900px;
  padding: var(--space-24) var(--space-24) 18px;
}

/* 13 Aug 2026: mobile-only. Default/collapsed state has zero space between
   the van photo and the trust strip below the hero (the grid's own
   row-gap plus .hero's bottom padding, both zeroed here) - .is-form-open
   (added by main.js in the same click handler that opens the panel)
   restores both so the revealed form has room to sit in. Scoped to the
   same <768px range as the rest of this collapse mechanism; tablet/
   desktop always show the form and never collapse, so they're untouched. */
@media (max-width: 767.98px) {
  .hero .container {
    gap: 0;
  }
  .hero {
    padding-bottom: 0;
  }
  .hero.is-form-open .container {
    gap: var(--space-32);
  }
  .hero.is-form-open {
    padding-bottom: var(--space-64);
  }
}

@media (min-width: 768px) {
  .hero-cta-btn {
    display: none;
  }
  .hero-microtrust {
    display: none;
  }
  #hero-form-panel {
    max-height: none;
    /* Was still the old 18px bottom padding - the sitewide
       .hero-form-wrap padding reduction to 10px never reached this
       instance, since this ID-scoped rule (specificity beats the class)
       had its own hardcoded copy of the old value. */
    padding: var(--space-24) var(--space-24) 10px;
    overflow: visible;
  }
}

@media (prefers-reduced-motion: reduce) {
  #hero-form-panel {
    transition: none;
  }
}

/* ---------- Generic section headers ---------- */
.section-heading {
  margin-bottom: var(--space-32);
}

/* Mobile/tablet only (<1024px, desktop's 32px is confirmed correct and
   untouched): every section heading site-wide sat too far from whatever
   follows it (a card grid, a link, a carousel) on small screens. Tightened
   to match the Credentials heading's own gap to its grid (16px), the
   already-correct reference point on this page. Fixed here at the shared
   class rather than per-section so it doesn't need patching again per
   heading. */
@media (max-width: 1023.98px) {
  .section-heading {
    margin-bottom: var(--space-16);
  }
}

.no-hidden-fees-heading {
  font-size: 20px;
}

@media (min-width: 1024px) {
  .no-hidden-fees-heading {
    font-size: 24px;
  }
}

/* ---------- Service highlight / anchor cards ---------- */
.card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-24);
}

@media (min-width: 640px) {
  .card-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 1024px) {
  .card-grid-4 {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-32);
  }
  .card-grid-3 {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-32);
  }
}

@media (min-width: 1366px) {
  .card-grid-4 {
    grid-template-columns: repeat(4, 1fr);
  }
}

.service-card {
  background: #fff;
  border-radius: 10px;
  padding: var(--space-24);
  box-shadow: var(--shadow-card);
  transition: transform 200ms ease-out, box-shadow 200ms ease-out;
  display: block;
  color: inherit;
  text-decoration: none;
}

@media (min-width: 1024px) {
  .service-card,
  .review-card {
    padding: var(--space-32);
  }
}

.service-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-hover);
}

@media (prefers-reduced-motion: reduce) {
  .service-card:hover {
    transform: none;
  }

  .quick-fact-action:hover {
    transform: none;
  }
}

.service-card h3 {
  margin-bottom: var(--space-8);
}

/* ---------- What We Do (photo cards) ---------- */
.what-we-do-heading {
  margin-bottom: var(--space-32);
}

.wwd-grid-large,
.wwd-grid-small {
  display: grid;
  grid-template-columns: 1fr;
  align-items: stretch;
  gap: var(--space-16);
}

.wwd-grid-large {
  margin-bottom: var(--space-16);
}

.wwd-grid-small {
  margin-top: var(--space-16);
}

@media (min-width: 640px) {
  .wwd-grid-large {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 1024px) {
  .wwd-grid-large,
  .wwd-grid-small {
    gap: var(--space-24);
  }

  .wwd-grid-small {
    grid-template-columns: 1fr 1fr 1fr;
  }
}

.wwd-card {
  background: #fff;
  border-radius: 10px;
  border: 1px solid var(--field-border);
  color: inherit;
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: transform 200ms ease-out, box-shadow 200ms ease-out;
}

.wwd-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-hover);
}

@media (prefers-reduced-motion: reduce) {
  .wwd-card:hover {
    transform: none;
  }
}

.wwd-card--accent {
  border-color: var(--red-pale);
}

/* Full-card invisible link, same technique as .quick-fact-tap-link on Contact:
   this is what makes the whole card tappable on mobile/tablet without the card
   itself being an <a> (which would make .wwd-see-details an invalid nested
   anchor). Removed entirely at 1024px+, where .wwd-see-details becomes the
   only link. Sits below .wwd-see-details in stacking order (z-index 1 vs 2) so
   a tap on the button still lands on the button specifically. */
.wwd-card-tap-link {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}

.wwd-card-tap-link:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(38, 127, 193, 0.35);
}

@media (min-width: 1024px) {
  .wwd-card-tap-link {
    display: none;
  }
}

.wwd-photo {
  position: relative;
  height: 120px;
  flex-shrink: 0;
  background: repeating-linear-gradient(135deg, #EDF1F5, #EDF1F5 10px, #E3E9EF 10px, #E3E9EF 20px);
}

.wwd-photo--lg {
  height: 160px;
}

.wwd-photo-caption {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-8);
  text-align: center;
  font-family: ui-monospace, monospace;
  font-size: 11px;
  color: var(--blue-dark);
}

.wwd-photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Per-photo crop anchors: these fixed-height cards force a wide letterbox
   crop at most breakpoints, so the default center point misses each photo's
   actual subject. Picked by inspecting each source photo, not one shared value. */
.wwd-photo-img--hot-water {
  /* Re-anchored from the logo (50% 22%) to the model plate + pipe fittings:
     the logo crop read as a flat panel/sign, not a hot water unit. This framing
     trades the big "Rinnai" wordmark for the smaller "Infinity A26" plate plus
     the visible valve/hose connections, which reads as plumbing equipment. */
  object-position: 50% 50%;
}

.wwd-photo-img--cooktop {
  object-position: 50% 92%; /* keeps all 4 burners + knobs, crops the tiled wall above */
}

.wwd-photo-img--plumbing {
  /* Different source photo (services-plumbing-2.jpg): the old crop only showed
     a smooth bowl curve with no cistern/seat-line, ambiguous at a glance. This
     one keeps the seat-lid line + toilet-roll holder in frame, unmistakably a toilet.
     Nudged from 60% to 66% so the tapering base is visible too, not just the lid. */
  object-position: 50% 66%;
}

.wwd-photo-img--gas-maintenance {
  /* Re-anchored 13 Aug 2026 for a new source photo (regulator + braided
     hose connection on an exterior wall) — the fitting sits low in the
     675x900 source, with blank wall filling the top ~half, so this needs
     to sit much lower than the old photo's 45%. Best estimate, not
     live-tested (Chrome verification off the table); flag for a follow-up
     tuning pass once viewed on a real device. */
  object-position: 50% 75%;
}

.wwd-photo-img--cylinder {
  /* Default guess — keeps the tank body + Fernz install label in frame over
     the ceiling pipework above and the base below. Same caveat as above. */
  object-position: 50% 55%;
}

.wwd-body {
  padding: var(--space-16) var(--space-16) var(--space-24);
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
}

@media (min-width: 1024px) {
  .wwd-body {
    padding: var(--space-24);
  }
}

.wwd-body p {
  font-size: 14px;
  color: var(--text-body);
  line-height: 1.55;
  margin: var(--space-8) 0 0;
  max-width: none;
}

/* Scoped to .wwd-body .wwd-brand (2 classes), not bare .wwd-brand (1 class):
   .wwd-body p (1 class + 1 type = higher specificity than a single class)
   would otherwise win the cascade on every property they both set. Font-size/
   weight/color now deliberately match .wwd-body p exactly (14px/400/
   var(--text-body)) -- .wwd-brand now holds full-sentence second-paragraph
   content on every card, not just short brand-preference notes, so it reads
   as the same body copy, not a visually distinct caption. .wwd-brand--sm no
   longer needs its own font-size (both are 14px now), rule removed. */
.wwd-body .wwd-brand {
  font-size: 14px;
  font-weight: 400;
  color: var(--text-body);
  margin-top: var(--space-8);
  margin-bottom: 14px;
  padding-top: var(--space-8);
  border-top: 1px solid var(--field-border);
}

/* nowrap by design: every card has 2-3 chips (never enough for the "wrap only
   if >=3 land on the second row" rule to actually trigger), so the row is
   sized to always fit on one line rather than risk an orphaned 1-2 chip wrap. */
.wwd-chips {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  margin-top: var(--space-8);
}

.wwd-chip {
  display: inline-block;
  font-size: 12.5px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 20px;
  background: var(--blue-pale);
  color: var(--navy);
  white-space: nowrap;
}

/* "See details" — reuses the exact rest/active colors and transition timing
   from .quick-fact-action (Contact page's Phone/Email cards): pale-blue-tint
   at rest, solid blue + white text when active. Radius is the site's
   standard 6px button radius, not the quick-fact card's own 12px, per spec.
   position:relative + z-index:2 lifts it above .wwd-card-tap-link (z-index 1)
   so it's individually tappable/clickable at every breakpoint, same technique
   already used for the copy-to-clipboard buttons on Contact's quick-facts. */
.wwd-see-details {
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  position: relative;
  z-index: 2;
  margin-top: auto;
  padding: 10px 20px;
  border-radius: var(--radius-btn);
  background: var(--blue-pale);
  border: 2.5px solid var(--blue);
  color: var(--blue-dark);
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
  transition: background-color 220ms ease, color 220ms ease;
}

.wwd-see-details:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(38, 127, 193, 0.35);
}

/* .is-active is toggled by main.js on touchstart/touchend on this element
   directly, for a visible color-fade on tap (mirrors the desktop :hover
   below, since :hover itself is unreliable/sticky on touch devices). */
.wwd-see-details.is-active {
  background: var(--blue);
  color: #fff;
}

@media (min-width: 1024px) {
  .wwd-see-details:hover {
    background: var(--blue);
    color: #fff;
  }
}

.wwd-cta {
  text-align: center;
  margin-top: var(--space-32);
}

.trust-signal {
  display: inline-block;
  max-width: 420px;
  margin-top: var(--space-12);
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--blue-dark);
  background: #fff;
  border: 3px solid var(--blue-tint);
  padding: 8px 16px;
  border-radius: 6px;
}

.trust-signal svg {
  width: 14px;
  height: 14px;
  vertical-align: -2px;
  margin-right: 6px;
  color: var(--blue-dark);
}

.job-photo {
  margin-top: var(--space-16);
  max-width: 340px;
  width: 100%;
  height: auto;
  border-radius: 8px;
  box-shadow: var(--shadow-card);
}

@media (min-width: 1024px) {
  .job-photo {
    max-width: 480px;
  }
}

/* ---------- About page: job photo justified row ---------- */
/* Scoped as .section.job-photos-section (2 classes) so it reliably beats
   the shared .section rule's own padding-top regardless of source order -
   same reason as every other same-specificity override already documented
   in this file (search "same-specificity"). Only the top is shortened; the
   section's normal bottom padding is left alone. */
.section.job-photos-section {
  padding-top: var(--space-8);
}

.job-photos-heading {
  margin-bottom: var(--space-24);
}

@media (max-width: 1023.98px) {
  .job-photos-heading {
    margin-bottom: var(--space-16);
  }
}

/* Lives outside .container (see about.html) so it can bleed to the true
   viewport edges on mobile (for the peek carousel) and, at very wide
   desktop viewports, grow past the standard 1240px container - neither of
   which is possible while nested inside an element with its own max-width
   cap. */
.job-photo-row {
  display: flex;
  gap: 10px;
}

.job-photo-row-img {
  border-radius: 8px;
  box-shadow: var(--shadow-card);
  object-fit: contain;
}

/* Mobile + tablet (<1024px): centered single-image peek carousel. Each
   image keeps its own natural aspect-ratio, sized off a shared WIDTH
   (80vw) rather than a shared height - the dominant/centered image reads
   as one large photo, with only a thin sliver of its neighbor peeking in
   at each edge. Height is auto per image (via its own aspect-ratio), so
   the row's total height is set by its tallest photo (the two portrait
   ones); shorter/landscape photos just sit vertically centered within
   that - never letterboxed on the image itself, just page whitespace
   around a naturally shorter photo, same as a normal mixed-ratio gallery.
   scroll-snap-align:center (not the old "start") is what makes each swipe
   land on a centered image; there's no wraparound, so it stops naturally
   at the first and last photo.

   Row padding is what lets the FIRST/LAST image reach true center too
   (without it, scrollLeft can't go negative, so image 1 would rest
   left-of-center at rest). Padding = (100vw - image width) / 2 = 10vw.
   Because every image now shares the same WIDTH (unlike the old
   shared-height version), this one value centers every image correctly,
   not just a specific first/last photo - no more "recompute this if the
   photo order changes" landmine. */
@media (max-width: 1023.98px) {
  .job-photo-row {
    gap: 10px;
    align-items: center;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    padding: 0 10vw;
  }
  /* max-width:none is required: the sitewide img{max-width:100%} reset
     (line ~90) would otherwise resolve against the row's own shrunk
     content box (100vw minus the 10vw peek-padding on each side) and cap
     every image back down to that, regardless of the width set below -
     the exact bug already hit and fixed once on the old shared-height
     version of this component. */
  .job-photo-row-img {
    width: 80vw;
    height: auto;
    max-width: none;
    flex: 0 0 auto;
    scroll-snap-align: center;
  }
}

/* Desktop (1024px+): classic CSS-only justified row, no JS math needed.
   flex-basis:0 + flex-grow set to each image's own aspect-ratio makes width
   proportional to that ratio while the row exactly fills its container;
   combined with the aspect-ratio property below, the resulting height comes
   out identical for all 4 images and self-adjusts to whatever height
   exactly fits the row's own max-width at any viewport - no manually-
   guessed pixel height, no overflow risk. Row's own width/centering here
   replicates .container's own values exactly (--container-max/
   --gutter-desktop), so this whole "typical laptop" range renders
   identically to before this section had its own wrapper. */
@media (min-width: 1024px) {
  .job-photo-row {
    max-width: var(--container-max);
    margin-left: auto;
    margin-right: auto;
    padding-left: var(--gutter-desktop);
    padding-right: var(--gutter-desktop);
  }
  .job-photo-row-img {
    flex-basis: 0;
    flex-shrink: 1;
    min-width: 0;
    height: auto;
  }
}

/* Screens meaningfully larger than a laptop only (1600px+, comfortably
   above every common laptop's logical width including 16" MacBook Pro's
   1728... actually most run ~1512-1536, so 1600 is the deliberate line -
   adjust this one value if that's not quite where "laptop" should end on
   real hardware): the row is allowed to grow past the standard 1160px
   content width, same "eat 1/3 of the growing side margin" formula as
   Home's price-card breakout, just re-anchored so it equals exactly
   1160px AT 1600px (no visible jump at the breakpoint) instead of at
   1024px. Nothing below 1600px is affected by this rule at all. */
@media (min-width: 1600px) {
  .job-photo-row {
    max-width: calc(626.67px + 33.34vw);
  }
}

.job-photo-row-img--hotwater {
  aspect-ratio: 933 / 1400;
}

@media (min-width: 1024px) {
  .job-photo-row-img--hotwater {
    flex-grow: 0.6664;
  }
}

.job-photo-row-img--cooktop {
  aspect-ratio: 1400 / 933;
}

@media (min-width: 1024px) {
  .job-photo-row-img--cooktop {
    flex-grow: 1.5005;
  }
}

.job-photo-row-img--exterior {
  aspect-ratio: 1400 / 1048;
}

@media (min-width: 1024px) {
  .job-photo-row-img--exterior {
    flex-grow: 1.3359;
  }
}

.job-photo-row-img--tap {
  aspect-ratio: 933 / 1400;
}

@media (min-width: 1024px) {
  .job-photo-row-img--tap {
    flex-grow: 0.6664;
  }
}

.job-photo-row-img--gasmaint {
  aspect-ratio: 675 / 900;
}

@media (min-width: 1024px) {
  .job-photo-row-img--gasmaint {
    /* flex-grow = the image's own aspect ratio (675/900), same formula as
       the other 4 photos in this row - keeps the justified row's height
       uniform across all 5 images now instead of 4. */
    flex-grow: 0.75;
  }
}

/* Carousel dot indicators - mobile/tablet only, hidden on the desktop
   justified row where there's nothing to scroll. Active dot is toggled by
   a scroll listener in main.js, not CSS alone (it tracks whichever image
   is nearest the row's own center, not just "the Nth one"). */
.job-photo-dots {
  display: none;
  justify-content: center;
  align-items: center;
  gap: 8px;
  margin-top: var(--space-16);
}

@media (max-width: 1023.98px) {
  .job-photo-dots {
    display: flex;
  }
}

.job-photo-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--field-border);
  transition: background-color 200ms ease, transform 200ms ease;
}

.job-photo-dot.is-active {
  background: var(--blue);
  transform: scale(1.25);
}

/* ---------- Service detail sections (Services page, desktop layout) ---------- */
.service-detail-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-24);
  align-items: start;
}

@media (min-width: 1024px) {
  .service-detail-grid {
    grid-template-columns: 1.15fr 1fr;
    gap: var(--space-48);
    align-items: center;
  }
  .service-detail-grid .job-photo,
  .service-detail-grid .image-placeholder {
    max-width: 100%;
    width: 100%;
    max-height: 480px;
    object-fit: cover;
    margin-top: 0;
  }

  /* Per-photo crop anchors: at a capped 480px height these portrait/near-square
     sources get cropped, so a single shared object-position would misframe most
     of them. Picked by inspecting each source photo, same approach as the
     wwd-photo-img--* anchors above. */
  .job-photo--gas-hot-water {
    object-position: 50% 35%; /* keeps the unit body in frame, crops the pipes/cable below */
  }
  .job-photo--gas-maintenance {
    /* Re-anchored 13 Aug 2026, second pass: Services page now uses its own
       dedicated source (services-gas-maintenance-2.jpg, a 2342x2342 SQUARE,
       not pre-cropped) - Home's card is untouched and keeps its own separate
       file/anchor (see .wwd-photo-img--gas-maintenance above). This crop box
       is only mildly landscape at desktop widths, so a square source barely
       gets cropped either way - 60% nudges slightly toward the fitting,
       which sits a little below center in the source. Best estimate, not
       live-tested (Chrome verification off the table). */
    object-position: 50% 60%;
  }
  .job-photo--gas-cooktop {
    object-position: 50% 50%; /* already a balanced, centered composition */
  }
  .job-photo--cylinder {
    object-position: 50% 42%; /* keeps the tank body in frame over the roofline/grass */
  }
  .job-photo--plumbing {
    object-position: 50% 55%; /* keeps the seat + bowl in frame, away from the cistern top */
  }

  /* Scoped to the service intro paragraph specifically (not FAQ answers, not
     the sitewide p/li rule) — a small desktop-readability bump for these five
     sections only. */
  .service-detail-grid h2 + p {
    font-size: 19px;
    line-height: 1.7;
  }
}

.service-detail-faqs {
  margin-top: var(--space-32);
}

@media (min-width: 1024px) {
  .service-detail-faqs {
    max-width: 700px;
  }
}

/* ---------- About page (desktop layout: photo/credentials sidebar beside bio text) ---------- */
.about-grid {
  display: grid;
  gap: var(--space-24);
  margin-top: var(--space-24);
  grid-template-areas:
    "photo"
    "text"
    "creds";
}

.about-photo {
  grid-area: photo;
  max-width: 240px;
  height: 240px;
  margin-top: 0;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: var(--shadow-card);
}

/* Mobile/tablet only: center the hero heading and photo (both were
   flush-left by default - a block div with no auto margins, and h1 with
   no text-align override). Desktop keeps the existing left-aligned
   layout untouched. */
@media (max-width: 1023px) {
  .about-hero-heading {
    text-align: center;
  }
  .about-photo {
    margin-left: auto;
    margin-right: auto;
  }
}

.about-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 25%;
}

.about-text {
  grid-area: text;
}

.about-rating-callout {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: var(--space-16);
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 15px;
  color: var(--navy);
  background: #fff;
  border: 3px solid var(--blue-tint);
  border-radius: 6px;
  padding: 8px 16px;
}

/* Mobile only: badge sits alone on its own row already (blocks above/below force
   that), just left-aligned by default since inline-flex is an inline-level box.
   Switching to a block-level flex box sized to its own content and centered via
   margin auto repositions it without touching its own look (padding/border/font/
   icon all unchanged) or anything else on the page. */
@media (max-width: 767.98px) {
  .about-rating-callout {
    display: flex;
    width: fit-content;
    margin-left: auto;
    margin-right: auto;
  }
}

.about-rating-callout svg {
  width: 16px;
  height: 16px;
  color: var(--blue-dark);
  flex-shrink: 0;
}

.about-creds {
  grid-area: creds;
  background: var(--navy);
  box-shadow: 0 8px 24px rgba(16, 54, 90, 0.28);
}

/* This box also carries .service-card for its base card look, but it isn't
   itself a link (only the reviews tile inside it is) - cancel the shared
   .service-card:hover lift so the whole box stays static. */
.about-creds:hover {
  transform: none;
  box-shadow: 0 8px 24px rgba(16, 54, 90, 0.28);
}

.about-creds h2 {
  color: #fff;
  text-align: center;
  margin-top: 0;
  margin-bottom: var(--space-16);
}

.creds-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-12);
}

@media (min-width: 640px) {
  .creds-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 1024px) {
  .creds-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-16);
  }
}

/* Mini-card per credential: lighter navy panel + border against the
   surrounding darker .about-creds background, so each item reads as its
   own tile rather than a row in a list. justify-content:center makes the
   vertical centering explicit (grid rows stretch tiles to equal height,
   so this isn't just incidental - it's what actually centers shorter
   content within a taller row). */
.creds-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: var(--space-8);
  background: var(--navy-2);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 10px;
  padding: var(--space-16);
}

/* Icons white, not blue - gold stays reserved exclusively for the
   Guarantee shield icon elsewhere on this page, not introduced here. */
.creds-tile-icon {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  stroke: #fff;
}

.creds-tile-primary {
  margin: 0;
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 17px;
  color: #fff;
  line-height: 1.3;
}

.creds-tile-number {
  font-size: 32px;
  font-weight: 800;
}

/* Reviews card: text bumped slightly above the baseline, but stays
   smaller than the 24px star row above it - stars are the dominant
   element, "100+ reviews" is secondary confirmation. Underlined +
   paired with an external-link arrow (same convention as .reviews-link
   elsewhere on the site) since this is the one tile in the grid that's
   actually a link out. */
.creds-tile-primary.creds-tile-reviews-text {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 18px;
  text-decoration: underline;
}

.creds-reviews-arrow {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  stroke: #fff;
}

.creds-tile-secondary {
  margin: 4px 0 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-support-on-navy);
  line-height: 1.4;
}

/* Shared by the two PGDB cards' subtext specifically, so they match each
   other exactly - bolder/bigger than the base secondary style used for
   "+ wider Auckland region", which stays the lighter tier. */
.creds-tile-secondary.creds-tile-secondary--strong {
  font-size: 15px;
  font-weight: 700;
}

/* Reviews card: the whole tile is a link to the site's existing Google
   reviews URL (same one used elsewhere). Link-reset only - no hover lift
   (that would match the other five static cards, which aren't links). A
   subtle border/shadow hover cue is added below instead, desktop-only
   since touch has no hover to rely on - mobile keeps the whole tile as
   the tap target regardless. */
.creds-tile-link {
  text-decoration: none;
}

@media (min-width: 1024px) {
  .creds-tile-link:hover {
    cursor: pointer;
    border-color: rgba(255, 255, 255, 0.45);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
  }
}

.creds-star-row {
  display: flex;
  gap: 2px;
}

.creds-star-row svg {
  width: 24px;
  height: 24px;
  fill: #fff;
}

/* Suburb tags reuse the shape of the homepage Areas We Cover "also
   servicing" tags (border + radius + compact padding), recolored for
   this dark navy surface rather than the light one they were built for. */
.creds-suburb-tags {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
}

.creds-suburb-tag {
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: var(--radius-btn);
  padding: 4px 10px;
  font-size: 14px;
  font-weight: 700;
  color: #fff;
}

@media (min-width: 1024px) {
  .about-grid {
    grid-template-columns: 1fr 1.15fr;
    grid-template-areas:
      "photo text"
      "creds creds";
    column-gap: var(--space-48);
    row-gap: var(--space-32);
    align-items: center;
  }
  .about-photo {
    max-width: 100%;
    width: 100%;
    height: 420px;
  }
}

.map-card {
  background: #fff;
  border-radius: 12px;
  padding: 28px 24px;
  box-shadow: var(--shadow-card);
}

/* ---------- Terms and Conditions page ---------- */
.terms-entity {
  font-weight: 600;
  color: var(--blue-dark);
  margin-top: var(--space-8);
}

/* Each numbered clause is its own wrapper (not just a bare h2 + p run) so
   the jump-chip landing highlight can outline the whole segment, not just
   the heading. Explicit margin rather than relying on the last child's own
   margin collapsing through the div, which would give inconsistent gaps. */
.terms-section + .terms-section {
  margin-top: var(--space-24);
}

/* Jump-nav chips: not sticky (the mobile call bar already occupies the
   bottom of the screen, a second pinned element would crowd it), so this
   is a plain in-flow row. Horizontal-scroll on narrow widths rather than
   wrapping to a second row. */
.terms-jump-nav-wrap {
  position: relative;
}

.terms-jump-nav {
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  margin: var(--space-16) 0 var(--space-24);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 4px;
  scrollbar-width: none;
}

/* Trailing-edge scroll cue: only shown (via JS toggling .has-more-right,
   based on real scrollLeft/scrollWidth) while there's more row to scroll
   to, and fades back out once the row is scrolled to its end. Navy-tinted
   fade (not the page's own white background) so it reads as a deliberate
   "more to scroll" cue rather than a barely-visible white-on-white blend. */
.terms-jump-nav-wrap::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 4px;
  width: 36px;
  background: linear-gradient(to right, rgba(16, 54, 90, 0), rgba(16, 54, 90, 0.28));
  pointer-events: none;
  opacity: 0;
  transition: opacity 200ms ease;
}

.terms-jump-nav-wrap.has-more-right::after {
  opacity: 1;
}

@media (min-width: 1024px) {
  .terms-jump-nav-wrap::after {
    display: none;
  }
}

.terms-jump-nav::-webkit-scrollbar {
  display: none;
}

.terms-jump-chip {
  flex-shrink: 0;
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  font-size: 13.5px;
  color: var(--blue-dark);
  background: var(--blue-pale);
  border: 1px solid var(--blue-tint);
  border-radius: 999px;
  padding: 6px 14px;
  white-space: nowrap;
  text-decoration: none;
  transition: background 150ms ease, border-color 150ms ease;
}

.terms-jump-chip:hover {
  background: var(--blue-tint);
  border-color: var(--blue-dark);
  color: var(--blue-dark);
}

#payment,
#overdue-accounts,
#compliance-certificates,
#applicable-law {
  scroll-margin-top: 88px;
}

/* Jump-chip landing highlight: applied on click (JS), before the smooth
   scroll finishes, so the outline is already visible as the page arrives -
   held solid for 1s, then fades via a transition rather than vanishing. */
.terms-anchor-highlight {
  outline: 3px solid var(--blue);
  outline-offset: 6px;
  border-radius: 6px;
  transition: outline-color 500ms ease;
}

.terms-anchor-highlight.terms-anchor-fade {
  outline-color: transparent;
}

/* Payment details card */
.terms-payment-card {
  background: #fff;
  border: 3px solid var(--blue-tint);
  border-radius: 12px;
  padding: var(--space-24);
  margin: var(--space-16) 0;
  max-width: 420px;
}

.terms-payment-field {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.terms-payment-field + .terms-payment-field {
  margin-top: var(--space-16);
}

.terms-payment-label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #64748b;
}

.terms-payment-value-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.terms-payment-value {
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 800;
  font-size: 18px;
  color: var(--navy);
}

.terms-payment-value--mono {
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  font-size: 16px;
}

@media (max-width: 360px) {
  .terms-payment-value--mono {
    font-size: 14px;
  }
}

/* Tight wrapper around just the button (not the whole value row, which
   stretches to the card's full width) - matches .quick-fact-copy-wrap's
   pattern, so position:relative + the tooltip's right:0 anchor correctly
   next to the button regardless of how short the preceding value text is. */
.terms-payment-copy-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.terms-payment-card .copy-btn {
  opacity: 1;
  color: var(--blue-dark);
}

/* Mobile/tablet: expand the tap target to 44x44 minimum without growing
   the visible icon or the row's layout footprint - padding grows the
   button's real hit area, an equal negative margin cancels its
   contribution back out of the flex row's sizing. Field spacing bumped
   slightly in the same breakpoint so adjacent expanded tap zones keep
   clear of each other. Desktop keeps the smaller, mouse-driven sizing. */
@media (max-width: 1023px) {
  .terms-payment-field + .terms-payment-field {
    margin-top: 20px;
  }
  .terms-payment-copy-wrap .copy-btn {
    padding: 14px;
    margin: -14px;
  }
  .terms-payment-copy-wrap .copy-btn svg {
    width: 22px;
    height: 22px;
  }
}

.terms-copy-all-wrap {
  position: relative;
  margin-top: var(--space-24);
  padding-top: var(--space-16);
  border-top: 1px solid var(--blue-pale);
}

.copy-btn.terms-copy-all-btn {
  opacity: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  background: var(--blue-pale);
  border: 1px solid var(--blue-tint);
  border-radius: var(--radius-btn);
  padding: 10px 16px;
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 14px;
  color: var(--blue-dark);
}

.copy-btn.terms-copy-all-btn:hover {
  background: var(--blue-tint);
}

.copy-btn.terms-copy-all-btn svg {
  width: 16px;
  height: 16px;
}

.terms-copy-all-wrap .copy-tooltip {
  top: -8px;
  right: 50%;
  transform: translate(50%, -100%);
}

.map-card h2 {
  margin-bottom: var(--space-8);
}

.map-embed {
  margin-top: var(--space-16);
  width: 100%;
  height: 360px;
  border: 0;
  border-radius: 8px;
}

.image-placeholder {
  margin-top: var(--space-16);
  height: 140px;
  border-radius: 8px;
  background: var(--blue-pale);
  border: 1px dashed var(--blue-tint);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--blue-dark);
  font-size: 12px;
  font-family: ui-monospace, monospace;
  text-align: center;
  padding: var(--space-8);
}

/* ---------- Trust strip (band below hero, report 07 §5.2) ---------- */
/* Rebuilt 22 July 2026: was white (blended into the rest of the mostly-white
   site, easily missed) — moved to a solid --blue band, the one place on the
   site this color becomes a section background rather than text/buttons,
   giving this "proof zone" its own identity distinct from both the navy hero
   above it and the pale "What we do" section below. Pitched as an Artifact
   mockup and approved, then sized up further per feedback that it still read
   small. */
.trust-strip {
  background: var(--blue);
  padding: var(--space-32) 0;
}

@media (max-width: 767.98px) {
  .trust-strip {
    /* Moved here from .hero-photo (13 Aug 2026) - same value, just
       relocated so the van photo sits flat and the trust strip reads as
       the floating element instead. */
    box-shadow: 0 -6px 14px rgba(0, 0, 0, 0.22), 0 6px 14px rgba(0, 0, 0, 0.22);
  }
}

.trust-strip-line {
  max-width: none;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  column-gap: var(--space-48);
  row-gap: var(--space-16);
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 20px;
  letter-spacing: -0.01em;
  color: #fff;
}

.trust-strip-line .strip-fact {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.trust-strip-line .strip-fact svg {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  color: #eaf3fb;
}

.trust-strip-line .strip-fact.is-rating svg {
  color: var(--gold);
}

.trust-strip-line .reviews-gap {
  margin-left: 12px;
}

@media (max-width: 900px) {
  .trust-strip-line {
    font-size: 17px;
    column-gap: var(--space-24);
  }
  .trust-strip-line .strip-fact svg {
    width: 20px;
    height: 20px;
  }
}

@media (max-width: 480px) {
  .trust-strip-line {
    font-size: 15.5px;
  }
  .trust-strip-line .strip-fact svg {
    width: 18px;
    height: 18px;
  }
}

/* 901px+ (tablet/desktop): forcing flex-wrap:nowrap here previously without
   confirming the content actually fit was wrong - individual facts have
   multiple words each, and once the row can't wrap between facts, a flex
   item that's still allowed to shrink wraps its OWN text mid-phrase instead
   ("PGDB" / "registered" stacked) instead of moving to a new line. Fixed
   two ways together: white-space:nowrap on each fact so a fact's own words
   can never split, and flex-wrap stays "wrap" (the line's own default) as
   a graceful fallback - if 5 facts ever still don't fit some exact width,
   whole facts move to a second row instead of a word breaking apart.
   Sizing is deliberately conservative and uniform across all of 901px+
   (no separate bigger tier past 1240px like before) so there's real margin
   or fit, not another guess that turns out wrong. */
@media (min-width: 901px) {
  .trust-strip-line {
    font-size: 22px;
    column-gap: var(--space-16);
  }
  .trust-strip-line .strip-fact {
    white-space: nowrap;
  }
  .trust-strip-line .strip-fact svg {
    width: 26px;
    height: 26px;
  }
}

/* ---------- Compact sticky trust strip (locks under header) ----------
   Same look/size on every screen and every page - only the *behavior*
   differs. On Home it starts empty and drops down once the full
   .trust-strip above has completely scrolled past (JS adds .is-stuck).
   On Services/About/Pricing/Contact it ships already open via .is-always
   baked into the HTML, no JS involved there.

   Home's instance is deliberately position:fixed (an overlay, not part of
   document flow) rather than position:sticky like the always-on pages:
   an earlier sticky-in-flow version caused a feedback loop where the strip
   growing shifted the very page position used to decide whether it should
   grow, so it flickered. position:fixed can't affect layout, which removes
   the loop entirely. Visually identical either way - this is purely an
   under-the-hood difference between the two behaviors. */
.trust-strip-compact {
  background: var(--blue);
  overflow: hidden;
  max-height: 0;
  transition: max-height 280ms ease-out;
  z-index: 98;
}

.trust-strip-compact:not(.is-always) {
  position: fixed;
  top: 72px;
  left: 0;
  right: 0;
}

.trust-strip-compact.is-always {
  position: sticky;
  top: 72px;
}

.trust-strip-compact.is-always,
.trust-strip-compact.is-stuck {
  max-height: 44px;
}

.trust-strip-compact .container {
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  color: #fff;
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 13.5px;
  white-space: nowrap;
  transform: translateY(-100%);
  transition: transform 280ms ease-out;
}

.trust-strip-compact.is-always .container,
.trust-strip-compact.is-stuck .container {
  transform: translateY(0);
}

.trust-strip-compact .fact {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.trust-strip-compact svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  color: #eaf3fb;
}

/* Rating fact: no gold anywhere here (gold stays locked to real review
   cards) - stars use the same off-white as every other icon in this bar.
   Two layouts, swapped by breakpoint, not just resized: mobile reads
   "4.9 [star] 100+ Reviews", tablet/desktop reads "[5 stars] 4.9 across
   100+ Reviews". Tablet intentionally matches desktop exactly (same
   breakpoint as the size bump below) rather than getting its own
   in-between treatment. */
.trust-strip-compact .rating-mobile,
.trust-strip-compact .rating-desktop {
  display: inline-flex;
  align-items: center;
}

.trust-strip-compact .rating-mobile {
  gap: 6px;
}

.trust-strip-compact .rating-mobile .rating-label {
  margin-left: 4px;
}

.trust-strip-compact .rating-desktop {
  display: none;
  gap: 10px;
}

.trust-strip-compact .star-row {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

/* Bigger screens (tablet + desktop, same treatment): bar stays 44px,
   text/icons get more prominent within it, and the rating fact swaps to
   the 5-star layout. */
@media (min-width: 768px) {
  .trust-strip-compact .container {
    gap: 28px;
    font-size: 17px;
    font-weight: 800;
  }
  .trust-strip-compact svg {
    width: 19px;
    height: 19px;
  }
  .trust-strip-compact .rating-mobile {
    display: none;
  }
  .trust-strip-compact .rating-desktop {
    display: inline-flex;
  }
}

/* ---------- Price transparency block (Homepage) ----------
   Mobile: section itself is the navy band, price rows are a plain list.
   Tablet (768px+): white section, navy card, price grid on top, rail stacked below inside the card.
   Desktop (1024px+): price grid and rail sit side by side inside the card. */
.price-section {
  background: var(--navy);
}

.price-section-heading {
  color: #fff;
}

.price-see-full {
  margin-top: var(--space-24);
}

.price-see-full a {
  color: #fff;
  font-weight: 600;
  text-decoration: underline;
}

.price-card {
  margin-top: var(--space-24);
  max-width: var(--container-max);
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--gutter-mobile);
  padding-right: var(--gutter-mobile);
}

.price-eyebrow {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--blue-tint);
  font-weight: 700;
  margin: 0 0 4px;
}

.price-cell {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}

.price-grid .price-cell:last-child {
  border-bottom: none;
}

.price-cell-icon {
  display: none;
}

.price-cell-text {
  display: flex;
  flex: 1;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.price-cell-title {
  display: flex;
  align-items: center;
  margin: 0;
}

.price-cell-label {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.25;
  color: #e7eef6;
}

.price-cell-tag {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gold);
  background: rgba(232, 169, 59, 0.14);
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 8px;
}

.price-cell-val {
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 800;
  font-size: 24px;
  line-height: 1.25;
  color: #fff;
  white-space: nowrap;
}

.price-note {
  font-size: 14px;
  color: #9fb4c9;
  margin: 18px 0 0;
  text-align: center;
}

.price-rail {
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  text-align: center;
}

.price-rail .price-rail-pending {
  background: rgba(255, 255, 255, 0.12);
  color: #cfe0ee;
}

.trust-cards {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
}

.guarantee-card {
  background: #fff;
  border-radius: 12px;
  border: 2px solid var(--blue);
  padding: 28px 24px;
  box-shadow: var(--shadow-soft);
  text-align: left;
}

.guarantee-card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-24);
}

@media (min-width: 640px) {
  .guarantee-card-grid {
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-32);
    align-items: start;
  }
}

.guarantee-card-col .guarantee-card-fine {
  margin-bottom: 0;
}

.guarantee-insurance-box {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  background: var(--blue-pale);
  border: 1px solid var(--blue-tint);
  border-radius: 8px;
  padding: 12px;
  margin-top: 16px;
  font-size: 14px;
  color: var(--navy);
}

.guarantee-insurance-box svg {
  flex-shrink: 0;
  margin-top: 2px;
}

.guarantee-card-head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 14px;
}

.guarantee-card-icon {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  background: #F6E2B3;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.guarantee-card-icon svg {
  width: 30px;
  height: 30px;
  stroke: var(--navy);
}

.response-strip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  max-width: 520px;
  margin: var(--space-24) auto 0;
  background: var(--blue-pale);
  border: 1px solid var(--blue-tint);
  border-radius: 8px;
  padding: 16px 24px;
  text-align: left;
}

.response-strip svg {
  width: 30px;
  height: 30px;
  stroke: var(--blue-dark);
  flex-shrink: 0;
}

.response-strip-stat {
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 800;
  font-size: 28px;
  color: var(--navy);
  white-space: nowrap;
  flex-shrink: 0;
}

.response-strip-divider {
  width: 1px;
  align-self: stretch;
  background: var(--blue-tint);
  flex-shrink: 0;
}

.response-strip-text {
  font-size: 14px;
  color: var(--navy);
  line-height: 1.3;
}

@media (max-width: 500px) {
  .response-strip {
    max-width: 100%;
  }
}

.guarantee-card-title {
  font-family: 'Schibsted Grotesk', sans-serif;
  font-size: 26px;
  font-weight: 800;
  color: var(--navy);
  line-height: 1.1;
}

.guarantee-card-title-sm {
  font-size: 19px;
  line-height: 1.25;
}

.guarantee-card-subtitle {
  font-size: 14px;
  font-weight: 600;
  color: var(--blue-dark);
  margin-top: 2px;
  display: block;
}

.guarantee-card-promise {
  color: var(--navy);
  font-size: 16px;
  font-weight: 700;
  line-height: 1.5;
  margin: 0 0 8px;
}

.guarantee-card-fine {
  color: #64748b;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.5;
  margin: 0;
}

.price-rail-proof-block {
  margin-top: 18px;
  padding-left: 14px;
  border-left: 3px solid rgba(232, 169, 59, 0.5);
}

.price-rail-stars {
  display: flex;
  gap: 2px;
  margin-bottom: 6px;
}

.price-rail-stars svg {
  width: 13px;
  height: 13px;
  fill: var(--gold);
}

.price-rail-proof {
  font-size: 14px;
  color: #b8cbdc;
  font-weight: 400;
  font-style: italic;
  line-height: 1.5;
  margin: 0;
}

.price-rail-proof .proof-attribution {
  display: block;
  margin-top: 4px;
  font-size: 14px;
  font-weight: 400;
  font-style: normal;
  color: #90a8bd;
}

.price-rail-cta {
  margin-top: 24px;
}

.price-cta-btn {
  display: block;
  width: 100%;
  box-sizing: border-box;
  font-size: 17px;
  padding: 16px;
  text-align: center;
}

.price-cta-phone {
  font-size: 14px;
  color: #b9cbdb;
  margin: 12px 0 0;
}

.price-cta-phone a {
  color: #fff;
  font-weight: 600;
  text-decoration: underline;
}

@media (min-width: 768px) {
  .price-section {
    background: transparent;
  }

  .price-section-heading {
    color: var(--navy);
  }

  .price-see-full a {
    color: var(--blue-dark);
    text-decoration: none;
  }

  .price-card-box {
    background: var(--navy);
    border-radius: 12px;
    padding: 24px 20px;
  }

  .price-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 24px;
  }

  .price-cell {
    align-items: center;
    gap: 12px;
    padding: 14px 0;
  }

  .price-grid .price-cell:last-child {
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
  }

  .price-grid .price-cell:nth-last-child(-n+2) {
    border-bottom: none;
  }

  .price-cell-icon {
    display: flex;
    width: 40px;
    height: 40px;
    border-radius: 9px;
    background: rgba(255, 255, 255, 0.1);
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
  }

  .price-cell-icon svg {
    width: 20px;
    height: 20px;
    stroke: var(--blue-tint);
  }

  .price-cell-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    flex: none;
    gap: 0;
  }

  .price-cell-title {
    flex-direction: column-reverse;
    align-items: flex-start;
  }

  .price-cell-tag {
    font-size: 9.5px;
    margin: 0 0 3px;
    background: transparent;
    padding: 0;
  }

  .price-cell-val {
    font-size: 20px;
    margin-top: 0;
  }

  .price-cta-btn {
    display: inline-block;
    width: auto;
    font-size: 15px;
    padding: 12px 28px;
  }
}

@media (min-width: 1024px) {
  .price-card {
    /* Breaks out past the standard 1240px container: eats exactly 1/3 of whatever
       white space would otherwise sit between the container and the viewport edge,
       on each side, so it scales correctly at any desktop width instead of a fixed guess. */
    max-width: calc(826.67px + 33.34vw);
    padding-left: var(--gutter-desktop);
    padding-right: var(--gutter-desktop);
  }

  .price-card-box {
    padding: 34px 38px;
    box-shadow: var(--shadow-card);
    display: flex;
    gap: 44px;
  }

  .price-rates {
    flex: 1.6;
  }

  .price-eyebrow {
    margin-bottom: 8px;
  }

  .price-cell {
    gap: 16px;
    padding: 18px 0;
  }

  .price-cell-icon {
    width: 54px;
    height: 54px;
    border-radius: 12px;
  }

  .price-cell-icon svg {
    width: 27px;
    height: 27px;
  }

  .price-cell-label {
    font-size: 16px;
  }

  .price-cell-tag {
    font-size: 11px;
  }

  .price-cell-val {
    font-size: 28px;
  }

  .price-note {
    text-align: left;
    margin-top: 20px;
  }

  .price-rail {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    border-top: none;
    border-left: 1px solid rgba(255, 255, 255, 0.15);
    padding: 0 0 0 34px;
    margin-top: 0;
    text-align: left;
  }

  .price-rail-cta {
    margin-top: 24px;
    text-align: center;
  }

  .price-cta-btn {
    font-size: 16px;
    padding: 14px 32px;
  }
}

/* ---------- How It Works (new, report 07 §5.6) ---------- */
.how-it-works-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-24);
  margin-top: var(--space-32);
}

@media (min-width: 640px) {
  .how-it-works-list {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 1024px) {
  .how-it-works-list {
    grid-template-columns: repeat(4, 1fr);
  }
}

.how-it-works-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--navy);
  color: #fff;
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 800;
  font-size: 15px;
  margin-bottom: var(--space-12);
}

.how-it-works-step h3 {
  margin-bottom: var(--space-8);
}

.how-it-works-step p {
  margin: 0;
  font-size: 15px;
}

/* ---------- Job photo strip placeholder (Proof section, report 07 §5.7) ---------- */
.job-photo-strip {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-16);
  margin-bottom: var(--space-32);
}

@media (min-width: 640px) {
  .job-photo-strip {
    grid-template-columns: repeat(4, 1fr);
  }
}

.job-photo-strip .image-placeholder {
  margin-top: 0;
  height: 120px;
}

.job-photo-strip img {
  width: 100%;
  height: 120px;
  object-fit: cover;
  border-radius: 8px;
  box-shadow: var(--shadow-card);
}

/* ---------- Areas served + Why a gas specialist (merged, 12 Aug 2026) ----------
   Areas column keeps its own pre-existing centered/max-width treatment
   unchanged below - it just centers within its own grid column now
   instead of the full container. Gas-first column is a plain
   supporting text block, no card/box, sized down relative to Areas. */
.areas-gas-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-32);
}

@media (min-width: 1024px) {
  .areas-gas-grid {
    grid-template-columns: 1.4fr 1fr;
    gap: var(--space-48);
    align-items: center;
  }
}

.gas-first-pitch {
  background: #fff;
  border: 2px solid var(--navy);
  border-radius: 10px;
  padding: var(--space-16);
  box-shadow: var(--shadow-card);
}

@media (min-width: 1024px) {
  .gas-first-pitch {
    max-width: 420px;
  }
}

.gas-first-heading {
  font-size: 20px;
  margin-bottom: var(--space-8);
}

.gas-first-copy {
  margin: 0;
}

/* ---------- Areas served (rebuilt, 31 Jul 2026) ---------- */
.areas-content {
  max-width: 600px;
  margin: 0 auto;
  text-align: center;
}

.areas-heading {
  font-size: 26px;
  font-weight: 800;
  margin-bottom: var(--space-8);
}

.areas-sub {
  font-size: 15px;
  line-height: 1.5;
  color: #667;
  max-width: 320px;
  margin: 0 auto var(--space-24);
}

.priority-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-12);
  margin-bottom: var(--space-24);
}

@media (min-width: 768px) {
  .priority-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.priority-card {
  background: var(--blue-pale);
  border-radius: var(--radius-btn);
  padding: var(--space-16);
  display: flex;
  align-items: center;
  gap: 14px;
  text-align: left;
}

.priority-icon {
  width: 40px;
  height: 40px;
  min-width: 40px;
  border-radius: var(--radius-btn);
  background: var(--blue);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
}

.priority-icon svg {
  width: 20px;
  height: 20px;
}

.priority-name {
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 17px;
  color: var(--navy);
}

.priority-tag {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--blue-dark);
  margin-top: 2px;
}

.also-label {
  display: block;
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue-dark);
  margin-bottom: var(--space-12);
}

.also-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-8);
  max-width: 340px;
  margin: 0 auto;
}

.also-cell {
  border: 1px solid var(--blue-tint);
  border-radius: var(--radius-btn);
  padding: 10px 12px;
  font-size: 14px;
  font-weight: 500;
  color: var(--navy);
  text-align: left;
}

/* ---------- Reviews / trust strip ---------- */
.reviews-aggregate {
  text-align: center;
  margin-bottom: var(--space-32);
}

.reviews-rating {
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 800;
  font-size: 36px;
  color: var(--navy);
}

.reviews-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  text-decoration: underline;
  font-weight: 500;
  margin-top: var(--space-8);
}

.reviews-asof {
  max-width: none;
  color: #667;
  font-size: 14px;
  margin-top: var(--space-4);
}

.review-card {
  background: #fff;
  border-radius: 10px;
  padding: var(--space-16);
  box-shadow: var(--shadow-card);
}

.review-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--navy);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 13px;
}

.review-header {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

.review-name {
  font-weight: 600;
  font-size: 13.5px;
}

.review-stars {
  color: var(--gold);
  font-size: 13px;
  margin-top: 2px;
}

.review-quote {
  font-size: 14px;
  margin: var(--space-12) 0 var(--space-8);
}

.review-meta {
  font-size: 12px;
  color: #667;
}

.review-pending {
  border: 2px dashed var(--blue-tint);
  background: var(--blue-pale);
  color: var(--blue-dark);
  font-size: 13px;
  font-family: ui-monospace, monospace;
}

/* ---------- FAQ accordion ---------- */
.faq-item {
  border-bottom: 1px solid var(--field-border);
}

.faq-question {
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  cursor: pointer;
  padding: var(--space-24) 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 15.5px;
  color: var(--navy);
}

.faq-question svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  transition: transform 250ms ease;
}

.faq-item.is-open .faq-question svg {
  transform: rotate(180deg);
}

.faq-answer {
  max-height: 0;
  overflow: hidden;
  transition: max-height 250ms ease;
}

.faq-answer p {
  padding-bottom: var(--space-24);
  font-size: 15px;
}

/* ---------- Rate cards (Pricing page, Design Spec §10) ---------- */
.rate-group {
  margin-top: var(--space-32);
}

.rate-group h3 {
  margin-bottom: var(--space-12);
}

.rate-section-gas {
  padding-top: 0;
}

.rate-group-heading {
  text-align: center;
  font-size: 28px;
  font-weight: 800;
  margin-bottom: var(--space-32);
}

.rate-group-heading::after {
  content: "";
  display: block;
  width: 56px;
  height: 3px;
  background: var(--blue);
  border-radius: 2px;
  margin: 12px auto 0;
}

@media (min-width: 1024px) {
  .rate-group-heading {
    font-size: 40px;
  }
}

.rate-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-16);
}

@media (min-width: 768px) {
  .rate-cards {
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  }
}

.rate-card {
  position: relative;
  background: #F7F9FB;
  border: 2px solid #D5DEE6;
  border-radius: 10px;
  padding: var(--space-16);
  padding-right: 40px;
  box-shadow: var(--shadow-rate-card);
}

.rate-card::after {
  content: "";
  position: absolute;
  top: 14px;
  right: 14px;
  width: 18px;
  height: 18px;
  background-repeat: no-repeat;
  background-size: contain;
  opacity: 0.35;
}

.rate-section-gas .rate-card::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2310365A' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'/%3E%3C/svg%3E");
}

.rate-section-plumbing .rate-card::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2310365A' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z'/%3E%3C/svg%3E");
}

.rate-category-tag {
  display: inline-block;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: #fff;
  background: var(--navy);
  padding: 3px 8px;
  border-radius: 4px;
  margin-bottom: var(--space-8);
}

.rate-card h4 {
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 700;
  font-size: 16px;
  color: var(--navy);
  margin: 0 0 var(--space-12);
}

.rate-kv {
  display: flex;
  justify-content: space-between;
  gap: var(--space-8);
  font-size: 14px;
  padding: 6px 0;
  border-top: 1px solid var(--field-border);
}

.rate-kv:first-of-type {
  border-top: none;
}

.rate-kv dt {
  color: #556;
}

.rate-kv dd {
  margin: 0;
  font-weight: 600;
  color: var(--navy);
  text-align: right;
}

.rate-flat-note {
  font-size: 15px;
  background: var(--blue-pale);
  border-radius: 8px;
  padding: var(--space-16);
  margin-top: var(--space-16);
}

/* ---------- Pending / placeholder blocks ---------- */
.pending-block {
  background: var(--blue-pale);
  border: 2px dashed var(--blue-tint);
  border-radius: 10px;
  padding: var(--space-24);
}

.pending-tag {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--navy);
  background: rgba(16, 54, 90, 0.08);
  padding: 4px 10px;
  border-radius: 4px;
  margin-bottom: var(--space-12);
}

.pending-block h3 {
  font-size: 18px;
}

.pending-block p {
  font-style: italic;
  color: #556;
}

/* ---------- Guarantee / confirmed trust blocks ---------- */
.guarantee-mention {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-12);
  background: #fff;
  border: 3px solid var(--blue);
  border-radius: 10px;
  padding: var(--space-16) var(--space-24);
}

.guarantee-mention-icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: #F6E2B3;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.guarantee-mention-icon svg {
  width: 24px;
  height: 24px;
  stroke: var(--navy);
}

.guarantee-mention-label {
  font-family: 'Schibsted Grotesk', sans-serif;
  font-weight: 800;
  font-size: 17px;
  color: var(--navy);
  flex-shrink: 0;
}

.guarantee-mention-divider {
  width: 1px;
  align-self: stretch;
  background: var(--blue-tint);
  flex-shrink: 0;
}

.guarantee-mention-text {
  margin: 0;
  font-size: 15px;
  color: var(--navy);
  line-height: 1.4;
}

.insurance-line {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  text-align: center;
  font-size: 15px;
  color: var(--text-body);
  margin: var(--space-16) 0;
}

.insurance-line svg {
  width: 18px;
  height: 18px;
  stroke: var(--blue-dark);
  flex-shrink: 0;
}

/* ---------- Utility ---------- */
.section {
  padding: var(--space-64) 0;
  scroll-margin-top: 88px;
}

.section-pale {
  background: var(--blue-pale);
}

.text-center {
  text-align: center;
  max-width: none;
}

/* Replaces an inline margin-top:32px (same value/reasoning as
   .section-heading above) so it can get the same mobile-only reduction
   without an inline style blocking the override. Desktop unchanged. */
.see-services-link {
  margin-top: var(--space-32);
}

@media (max-width: 1023.98px) {
  .see-services-link {
    margin-top: var(--space-16);
  }
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
}
