/* ═══════════════════════════════════════════════════════════════════
   SCROLL PERFORMANCE — keep promotions minimal. Too many promoted
   layers thrash the compositor; only promote elements that ACTIVELY
   animate during scroll.
   ═══════════════════════════════════════════════════════════════════ */

/* Hero backdrop has continuous Ken Burns — pin to its own layer */
.hero--home::before {
  transform: translateZ(0);
  will-change: transform;
  backface-visibility: hidden;
}

/* Scroll-driven reveal targets only */
.scroll-content-reveal,
.scroll-bg-reveal::before {
  transform: translateZ(0);
  backface-visibility: hidden;
}

/* Smooth scroll — let Lenis handle wheel, opt out of native smooth */
html.lenis-smooth {
  scroll-behavior: auto;
}
.lenis-smooth body {
  overflow: visible;
}
html, body {
  overscroll-behavior-y: none;
}

/* ═══════════════════════════════════════════════════════════════════
   POLISH LAYER — loaded after styles.css
   Additive refinements: type hierarchy, hero, animation moments,
   mobile improvements. Does not replace existing styles.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
}

/* ── Reset paragraph wrap for all body copy ─────────────────────── */
p, .lead {
  text-wrap: pretty;
}

h1, h2, h3 {
  text-wrap: balance;
}

/* .stack uses display:grid with no explicit grid-template-columns,
   which lets child elements with width:min(1360px, 100%) push the
   implicit grid track wider than the parent on narrow viewports.
   Pin the column to minmax(0, 1fr) so children can't overflow. */
.stack {
  grid-template-columns: minmax(0, 1fr);
}

/* Tablet portrait (641-980px): styles.css collapses every multi-column
   grid to 1fr, which wastes horizontal space at iPad widths. Restore
   intelligent 2-column layouts where they make sense. */
@media (min-width: 641px) and (max-width: 980px) {
  .grid--4,
  .grid--3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Global keyboard focus outline. :focus-visible only matches when the
   browser thinks the user is navigating with the keyboard, so mouse
   clicks won't show the outline. Existing component-specific :focus
   styles still apply on top of this baseline. */
:focus-visible {
  outline: 2px solid var(--brand-aqua, #23c7dc);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Skip-to-content link for keyboard users. Visually hidden until
   focused — then it appears as an aqua chip at top-left. */
.skip-link {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.skip-link:focus {
  position: fixed;
  left: 16px;
  top: 16px;
  width: auto;
  height: auto;
  padding: 12px 22px;
  background: var(--brand-aqua, #23c7dc);
  color: var(--brand-navy, #071625);
  z-index: 1000;
  font-family: "Montserrat", "Poppins", Arial, sans-serif;
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-decoration: none;
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(7, 22, 37, 0.22);
}

/* Section h2s: keep them single-line on desktop. Short copy lets us
   safely use a tighter clamp — they fall back to balanced wrap on
   narrow viewports.                                                 */
.section h2 {
  max-width: none;
}

/* ── HEADER PHONE CTA: "Call Today" crossfades to number on hover
   Both labels stack in the same grid cell so the button sizes to
   the wider one ("0408 822 719") — nothing shifts on hover.       */
.header-phone {
  position: relative;
}

.header-phone__swap {
  display: inline-grid;
  grid-template-areas: "swap";
  align-items: center;
  justify-items: center;
  margin-left: 4px;
}

.header-phone__a,
.header-phone__b {
  grid-area: swap;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  font-family: "Poppins", Arial, Helvetica, sans-serif;
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  transition: opacity 520ms var(--ease-out-quart);
}

.header-phone__a { opacity: 1; }
.header-phone__b { opacity: 0; pointer-events: none; }

/* Slight stagger: outgoing fades a touch faster than incoming for
   a smoother crossfade without dead-frame in the middle.          */
.header-phone:hover .header-phone__a,
.header-phone:focus-visible .header-phone__a {
  opacity: 0;
  transition-duration: 360ms;
}

.header-phone:hover .header-phone__b,
.header-phone:focus-visible .header-phone__b {
  opacity: 1;
  transition-delay: 80ms;
}

/* Touch devices: show number by default */
@media (hover: none) and (pointer: coarse) {
  .header-phone__a { opacity: 0; }
  .header-phone__b { opacity: 1; }
}
.main-nav > a,
.nav-item--dropdown > a {
  position: relative;
  padding: 6px 0;
}

@media (min-width: 981px) {
  .main-nav > a::after,
  .nav-item--dropdown > a::after {
    content: "";
    position: absolute;
    left: 50%;
    right: 50%;
    bottom: 0;
    height: 2px;
    background: var(--brand-aqua);
    transition: left 280ms var(--ease-out-quart), right 280ms var(--ease-out-quart);
    border-radius: 2px;
  }

  .main-nav > a:hover::after,
  .main-nav > a:focus::after,
  .nav-item--dropdown:hover > a::after,
  .nav-item--dropdown:focus-within > a::after {
    left: 0;
    right: 0;
  }
}

/* ── PERFORMANCE: smoother scroll scrubbing ─────────────────────
   The base CSS uses ~9 simultaneous animation-timeline: view()
   animations PLUS two position: fixed hero layers. On a 60Hz
   display the compositor falls behind during fast scrolls and
   the scroll-driven scrubs look stepped/janky.

   Fixes:
   • Force GPU layers on the fixed hero bg + watermark so they
     compose, not repaint, on each frame.
   • Drop the Ken Burns animation — animating a fixed-position
     background-size + transform forces continuous fullscreen
     repaints that contend with every other scroll animation.
   • Add content-visibility on below-fold sections so the
     browser can skip their layout/paint until they approach.
   • Reduce the watermark layer's filter complexity during scroll.
   ─────────────────────────────────────────────────────────────── */

/* Lenis owns smooth scrolling on desktop; native scroll-behavior would
   fight it. Keep native smooth disabled — the document/body rules at
   the top of this file already handle the Lenis case. */
html {
  scroll-behavior: auto;
}

/* GPU-promote the two fixed hero layers so the compositor handles
   them, instead of the renderer repainting on every scroll tick.  */
.hero--home::before,
.hero--home::after {
  will-change: transform, opacity;
  transform: translateZ(0);
  backface-visibility: hidden;
}

/* Light promotion for scroll-reveal targets. `will-change` was here
   permanently which forced GPU layers on 10-20 elements site-wide —
   keep only the backface trick which is cheap, and let the browser
   decide whether to promote based on the actual animations on each
   element (the @supports view-timeline rules trigger promotion only
   while scrolling near them). */
.scroll-content-reveal,
.scroll-bg-reveal {
  backface-visibility: hidden;
}

/* Below-the-fold sections: skip layout/paint until near viewport
   for cheaper initial render. Only apply to wrappers WITHOUT
   scroll-driven animation children — `content-visibility: auto`
   creates a `contain: size layout style paint` boundary that mis-
   measures nested elements riding `animation-timeline: view()`,
   so the process-showcase + home-trust-section cards "popped"
   into place instead of scrubbing. Limit to `.section--paper`
   which holds simpler content. */
/* content-visibility on section wrappers was muting the
   contain-size measurement of scroll-driven children (the offer
   cards and process showcase cards inside .section--paper grids
   appeared all at once instead of scrubbing). Disabled. The perf
   win was small; correct scroll animation is more important. */

/* The reviews section sits right after the hero — keep it eager
   so the user never sees a flash of unfilled space.              */
.section--reviews-bg {
  content-visibility: visible;
}

/* Eyebrow above the H1 — small caps, aqua, with thin lines */
.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--brand-blue);
  opacity: 0;
  animation: fade-up-in 1300ms var(--ease-out-quart) 250ms forwards;
}

.hero__eyebrow::before,
.hero__eyebrow::after {
  content: "";
  width: 28px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--brand-aqua));
  display: inline-block;
}

.hero__eyebrow::after {
  background: linear-gradient(90deg, var(--brand-aqua), transparent);
}

/* Eyebrow chip variant — same hairline-on-both-sides treatment as the
   hero eyebrow, reusable on any section eyebrow (e.g. "Why Be Clean").
   Higher specificity needed because the broader consolidated eyebrow
   rules appear LATER in this file and would otherwise win ties. */
.process-showcase .section-intro .eyebrow.eyebrow--rule,
.section .eyebrow.eyebrow--rule,
.eyebrow.eyebrow--rule {
  display: inline-flex !important;
  align-items: center;
  gap: 14px;
  margin-left: auto;
  margin-right: auto;
}

.process-showcase .section-intro .eyebrow.eyebrow--rule::before,
.process-showcase .section-intro .eyebrow.eyebrow--rule::after,
.section .eyebrow.eyebrow--rule::before,
.section .eyebrow.eyebrow--rule::after,
.eyebrow.eyebrow--rule::before,
.eyebrow.eyebrow--rule::after {
  content: "";
  width: 28px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--brand-aqua));
  display: inline-block;
  margin: 0;
  vertical-align: baseline;
  transform: none;
}

.process-showcase .section-intro .eyebrow.eyebrow--rule::after,
.section .eyebrow.eyebrow--rule::after,
.eyebrow.eyebrow--rule::after {
  background: linear-gradient(90deg, var(--brand-aqua), transparent);
}

/* H1 — size to viewport, allow natural wrap, no width tricks.
   The base styles.css @media (min-width: 981px) forces white-space:
   nowrap which is fine — the line fits at desktop widths. Below
   981px we let it wrap naturally and balance.                     */
.hero--home h1 {
  font-size: clamp(2.2rem, 5.2vw, 4rem);
  letter-spacing: 0.015em;
  line-height: 1.06;
  font-weight: 500;
  max-width: none;
  margin: 0 auto;
  text-wrap: balance;
}

/* Whole-H1 fade-up reveal (used on non-home heroes that adopt
   .hero--home — case-studies, service pages — where the H1 isn't
   per-word staged). Specificity beats styles.css .hero--home h1.
   No blur on the H1 itself — large text reads as "not crisp" with
   any blur filter; keep the blur on the smaller lead/locations
   where it reads as gentle softening instead. */
.hero--home h1.hero-h1-reveal {
  opacity: 0;
  transform: translateY(12px);
  animation: fade-up-in 1200ms var(--ease-out-quart) 500ms forwards;
}

/* Per-word staged H1 (home page). Each word fades up independently
   so "When" lands first, "Presentation" second, and the italic
   "Matters" arrives last as the punchline. Durations and delays are
   tuned so each word's entrance bleeds into the next — no hard
   beats, the cascade feels presented rather than thrown. */
.hero--home h1.hero-h1-staged > span {
  display: inline-block;
  opacity: 0;
  transform: translateY(12px);
}

.hero--home h1.hero-h1-staged > span:nth-of-type(1) {
  animation: fade-up-in 1200ms var(--ease-out-quart) 700ms forwards;
}

.hero--home h1.hero-h1-staged > span:nth-of-type(2) {
  animation: fade-up-in 1300ms var(--ease-out-quart) 1100ms forwards;
}

.hero--home h1.hero-h1-staged > span.word--accent {
  animation: fade-up-in 1600ms var(--ease-out-quart) 1600ms forwards;
}

/* Default fade-up-in: used by eyebrow, lead, locations, actions, and
   the leading words of the staged H1. Distance is small so the motion
   feels like a settle rather than a jump. */
@keyframes fade-up-in {
  0%   { opacity: 0; transform: translateY(10px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* Atmospheric variant — softens in from a slight blur. Used on the
   lead and locations row. Opacity ramps slowly so the text emerges
   rather than appears. */
@keyframes fade-up-in-soft {
  0%   { opacity: 0; transform: translateY(12px); filter: blur(3px); }
  100% { opacity: 1; transform: translateY(0); filter: blur(0); }
}

.hero--home h1 .word--accent {
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-weight: 600;
  font-style: italic;
  color: var(--brand-aqua);
  letter-spacing: -0.005em;
  margin-left: 0.04em;
}

/* Lead and locations use the atmospheric "typed-in blurry, rendered
   clean" variant — short blur(3px) at the start, sharp at the end.
   Buttons stay on the plain fade-up so they're crisp from the moment
   they appear (don't want to blur an actionable element). */
.hero--home .lead,
.hero--home .hero__locations {
  opacity: 0;
  filter: blur(3px);
  animation: fade-up-in-soft 1400ms var(--ease-out-quart) forwards;
}

.hero--home .hero__actions {
  opacity: 0;
  animation: fade-up-in 1100ms var(--ease-out-quart) forwards;
}

/* Default cascade (service / about / case-studies / area-list pages
   whose H1 is single-element via .hero-h1-reveal). Faster than home
   because there's only one H1 to wait for — the eye doesn't need a
   per-word stagger window. Each follow-on still overlaps the prior. */
.hero--home .lead            { animation-delay: 1200ms; }
.hero--home .hero__locations { animation-delay: 1500ms; }
.hero--home .hero__actions   { animation-delay: 1700ms; }

/* Home overrides — the staged H1 lasts longer, so push everything
   after it out to match. Uses :has() so this only applies on the
   home page where the staged H1 exists. Each follow-on overlaps the
   tail of the prior element by about 200ms for a continuous feel. */
.hero--home:has(.hero-h1-staged) .lead            { animation-delay: 2700ms; }
.hero--home:has(.hero-h1-staged) .hero__locations { animation-delay: 3000ms; }
.hero--home:has(.hero-h1-staged) .hero__actions   { animation-delay: 3300ms; }

/* Non-home heroes (service / about / case-studies / areas) only have
   eyebrow, H1, lead, and buttons — no audience pills or locations row.
   Tighten the stack gap so the cascade feels denser, not airy.
   Home stays at 28px because it has 6 stacked elements. */
.hero--home:not(:has(.hero-h1-staged)) .hero__content {
  gap: 20px;
}

/* ── Maintenance band (home page) ─────────────────────────────
   Strategic priority: position recurring maintenance as the
   premium asset-protection move, not as a service-page detail. */
.section--maintenance {
  padding: clamp(48px, 7vh, 88px) 0;
}

.maintenance__layout {
  align-items: center;
  gap: clamp(28px, 4vw, 60px);
}

.maintenance__media {
  border-radius: var(--radius, 18px);
  overflow: hidden;
  background: var(--brand-navy, #071625);
}

.maintenance__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center 35%;
  display: block;
}

.maintenance__media .media-block__caption {
  border-radius: 0 0 var(--radius, 18px) var(--radius, 18px);
}

.maintenance__copy h2 {
  margin-bottom: 8px;
}

@media (max-width: 980px) {
  .maintenance__media { margin-bottom: 18px; }
}

/* ── Documentation-as-asset band (home page) ──────────────────
   Positions the BCR / completion report as a deliverable, not a
   process step. Two-column split: copy on left, mock report
   thumbnail on right. The thumbnail uses brand fonts/colours and
   placeholder content — no client info — so it shows the visual
   format buyers receive without breaching confidentiality. */
.section--documentation {
  padding: clamp(64px, 9vh, 110px) 0;
}

.documentation__layout {
  align-items: center;
  gap: clamp(32px, 5vw, 72px);
}

.documentation__copy h2 {
  margin-bottom: 8px;
}

.documentation__uses {
  list-style: none;
  padding: 0;
  margin: 22px 0 6px;
  display: grid;
  gap: 14px;
}

.documentation__uses li {
  position: relative;
  padding-left: 26px;
  font-size: 0.98rem;
  line-height: 1.55;
  color: var(--muted);
}

.documentation__uses li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 16px;
  height: 2px;
  background: var(--brand-aqua);
  border-radius: 2px;
}

.documentation__uses strong {
  color: var(--brand-navy);
  font-weight: 700;
  margin-right: 4px;
}

.documentation__pricing {
  margin: 22px 0 6px;
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brand-blue);
}

.documentation__ppr {
  margin-top: 10px;
  font-weight: 600;
  color: var(--brand-blue);
}
.documentation__ppr::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--brand-aqua);
  vertical-align: middle;
}

.documentation__pricing span {
  color: rgba(10, 41, 72, 0.54);
}

.documentation__pricing strong {
  font-weight: 700;
  letter-spacing: 0.04em;
}

/* Mock report thumbnail — visual prop, not a real document. */
.documentation__visual {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Mock BCR cover — faithful CSS rebuild of the real Building Condition
   Report cover sheet. Sample data only (no client info). Top 64% is
   the navy gradient hero with brand row, title, and metadata grid.
   Bottom 36% is the white "purpose" block with the three pillars. */
.mock-report {
  position: relative;
  width: min(420px, 100%);
  aspect-ratio: 3 / 4;
  background: #fff;
  border-radius: 14px;
  box-shadow:
    0 30px 60px rgba(7, 22, 37, 0.18),
    0 0 0 1px rgba(17, 74, 115, 0.08),
    inset 0 1px 0 rgba(255, 255, 255, 0.8);
  overflow: hidden;
  transform: rotate(-2deg);
  backface-visibility: hidden;
  will-change: transform;
  transition: transform 600ms var(--ease-out-quart);
  display: grid;
  grid-template-rows: 64% 36%;
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
}

.documentation__visual:hover .mock-report {
  transform: rotate(0deg) translateY(-6px) scale(1.08);
}

/* ── Top hero — navy gradient with watermark + brand + title ─── */
.mock-report__hero {
  position: relative;
  padding: 18px 20px 16px;
  background:
    linear-gradient(135deg, #0a2948 0%, #114a73 70%, #1a6493 100%);
  color: #fff;
  overflow: hidden;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 12px;
}

/* House watermark — large outline echoing the real BCR cover */
.mock-report__watermark {
  position: absolute;
  right: -36px;
  bottom: -28px;
  width: 220px;
  height: 220px;
  background-image: url("../brand/final/watermark-icon.svg");
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
  opacity: 0.08;
  pointer-events: none;
}

/* Brand + contact strip */
.mock-report__brand-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  position: relative;
  z-index: 1;
}

.mock-report__brand {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.mock-report__brand-name {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: #fff;
  line-height: 1;
}

.mock-report__brand-tag {
  font-size: 0.42rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.6);
}

.mock-report__contact {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
  text-align: right;
  font-size: 0.42rem;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.72);
  line-height: 1.25;
}

/* The big title — "Building Condition Report" */
.mock-report__big-title {
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: 1.55rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1;
  color: #fff;
  margin: 0;
  align-self: end;
  position: relative;
  z-index: 1;
}

/* Metadata 2x2 grid (CLIENT / REFERENCE / INSPECTED / ASSESSED BY) */
.mock-report__meta-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 18px;
  margin: 0;
  position: relative;
  z-index: 1;
}

.mock-report__meta-grid > div {
  display: grid;
  gap: 2px;
}

.mock-report__meta-grid dt {
  font-size: 0.42rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brand-aqua);
}

.mock-report__meta-grid dd {
  margin: 0;
  font-size: 0.6rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: #fff;
  line-height: 1.15;
}

.mock-report__ref {
  font-variant-numeric: tabular-nums;
}

/* Full-width site address row */
.mock-report__site {
  display: grid;
  gap: 2px;
  position: relative;
  z-index: 1;
}

.mock-report__site-label {
  font-size: 0.42rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brand-aqua);
}

.mock-report__site-value {
  font-size: 0.6rem;
  color: #fff;
  font-weight: 500;
}

/* ── Bottom purpose block — white ───────────────────────────── */
.mock-report__purpose {
  padding: 14px 20px 16px;
  display: grid;
  grid-template-rows: auto auto 1fr;
  gap: 8px;
  background: #fff;
}

.mock-report__purpose-label {
  font-size: 0.42rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brand-aqua);
}

.mock-report__purpose-headline {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--brand-navy, #0a2948);
  margin: 0;
  letter-spacing: -0.005em;
  line-height: 1.2;
}

.mock-report__pillars {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
  align-self: end;
}

.mock-report__pillars li {
  display: grid;
  justify-items: start;
  gap: 4px;
}

/* Pillar icon — small aqua circle with a tick/dot pattern */
.mock-report__pillar-icon {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--brand-aqua) 0%, var(--brand-aqua) 55%, transparent 56%),
              radial-gradient(circle at center, transparent 60%, rgba(35, 199, 220, 0.18) 61%, rgba(35, 199, 220, 0.18) 100%);
}

.mock-report__pillar-title {
  font-size: 0.42rem;
  font-weight: 700;
  color: var(--brand-navy, #0a2948);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  line-height: 1.25;
}

@media (max-width: 980px) {
  .documentation__visual { margin-top: 24px; }
  .mock-report { width: min(360px, 90%); transform: rotate(-1.5deg); }
}

/* ── About page owner pull-quote ────────────────────────────────
   Sits between the proof highlights and the "right clean" section.
   First-person from Brodie. Editorial type, large opening quote,
   right-aligned attribution. */
.about-owner-quote {
  padding: clamp(40px, 7vh, 88px) 0 clamp(32px, 5vh, 64px);
}

.owner-quote {
  position: relative;
  max-width: 760px;
  margin: 0 auto;
  padding: 12px 0 0 clamp(36px, 6vw, 72px);
}

.owner-quote__mark {
  position: absolute;
  top: -14px;
  left: -6px;
  font-family: "Montserrat", "Poppins", Georgia, serif;
  font-size: clamp(88px, 12vw, 144px);
  line-height: 1;
  color: var(--brand-aqua);
  font-weight: 600;
  user-select: none;
  pointer-events: none;
}

.owner-quote__body {
  margin: 0;
  display: grid;
  gap: 14px;
  font-family: "Poppins", Arial, Helvetica, sans-serif;
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  line-height: 1.55;
  color: var(--ink, #0a2948);
  letter-spacing: 0.005em;
  font-weight: 400;
}

.owner-quote__body p {
  margin: 0;
}

.owner-quote__body p:first-child::first-letter {
  font-weight: 500;
}

.owner-quote__attrib {
  margin-top: 22px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  gap: 2px;
}

.owner-quote__name {
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--brand-navy, #0a2948);
}

.owner-quote__role {
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brand-aqua);
}

@media (max-width: 640px) {
  .owner-quote {
    padding-left: clamp(28px, 8vw, 48px);
  }
  .owner-quote__mark {
    top: -10px;
    font-size: 80px;
  }
}

/* ── Service-page trust strip ──────────────────────────────────
   Direct-from-Google visitors landing on a service page never saw
   the proof stack from the home (locally owned, $20M cover, etc).
   This compressed 4-pill row sits directly under the hero so the
   trust signal is front-loaded for every page. */
.section--proof {
  padding: 18px 0 8px;
  background: transparent;
}

.proof-strip-band {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 14px;
}

.proof-strip-band .proof-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 38px;
  padding: 8px 16px 8px 14px;
  background: rgba(255, 255, 255, 0.42);
  border: 1px solid rgba(35, 199, 220, 0.34);
  border-radius: 999px;
  backdrop-filter: blur(8px) saturate(140%);
  -webkit-backdrop-filter: blur(8px) saturate(140%);
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brand-blue);
  white-space: nowrap;
  transition: transform 280ms var(--ease-out-quart), background 280ms ease, border-color 280ms ease;
}

.proof-strip-band .proof-pill svg {
  width: 14px;
  height: 14px;
  color: var(--brand-aqua);
  stroke-width: 1.6;
  flex-shrink: 0;
}

.proof-strip-band .proof-pill:hover {
  transform: translateY(-2px);
  background: rgba(255, 255, 255, 0.72);
  border-color: rgba(35, 199, 220, 0.62);
}

@media (max-width: 640px) {
  .proof-strip-band {
    gap: 6px 8px;
  }
  .proof-strip-band .proof-pill {
    min-height: 32px;
    padding: 6px 12px 6px 10px;
    font-size: 0.6rem;
    letter-spacing: 0.14em;
  }
  .proof-strip-band .proof-pill svg {
    width: 12px;
    height: 12px;
  }
}

/* Audience chips — sits below the lead on the home hero. Lets each
   buyer self-identify ("for sale prep" / "managed properties" /
   "coastal homes worth protecting") without diluting the H1. */
.hero--home .hero__audience {
  list-style: none;
  padding: 0;
  margin: 14px auto 6px;
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  opacity: 0;
  filter: blur(3px);
  animation: fade-up-in-soft 1400ms var(--ease-out-quart) 2400ms forwards;
  animation-timeline: auto;
}

.hero--home:has(.hero-h1-staged) .hero__audience {
  animation-delay: 2850ms;
}

.hero--home .hero__audience li {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(35, 199, 220, 0.34);
  backdrop-filter: blur(8px) saturate(140%);
  -webkit-backdrop-filter: blur(8px) saturate(140%);
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brand-blue);
  white-space: nowrap;
}

@media (max-width: 640px) {
  .hero--home .hero__audience {
    gap: 6px;
  }
  .hero--home .hero__audience li {
    font-size: 0.62rem;
    letter-spacing: 0.14em;
    padding: 5px 11px;
  }
}

/* Locations row — animated dot separators */
.hero--home .hero__locations {
  font-size: 0.74rem;
  letter-spacing: 0.36em;
  font-weight: 600;
  text-transform: uppercase;
  color: rgba(10, 41, 72, 0.66);
  display: inline-flex;
  align-items: center;
  gap: 18px;
  margin: 4px 0;
}

.hero--home .hero__locations::before,
.hero--home .hero__locations::after {
  display: none;
}

/* Scroll indicator — centred via inset+margin-auto so the animation
   transform doesn't need to carry a centering translate.          */
.hero__scroll-cue {
  position: absolute;
  left: 0;
  right: 0;
  margin-inline: auto;
  width: max-content;
  bottom: clamp(28px, 4vh, 56px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.62rem;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: rgba(10, 41, 72, 0.42);
  opacity: 0;
  transform: translateY(14px);
  animation: scroll-cue-in 1300ms var(--ease-out-quart) 3500ms forwards;
  z-index: 2;
  pointer-events: none;
}

@keyframes scroll-cue-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

.hero__scroll-cue__bar {
  width: 1px;
  height: 44px;
  background: linear-gradient(180deg, rgba(35, 199, 220, 0.6), transparent);
  position: relative;
  overflow: hidden;
}

.hero__scroll-cue__bar::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, var(--brand-aqua-light), transparent 60%);
  animation: scroll-cue 2.4s ease-in-out infinite;
}

@keyframes scroll-cue {
  0%   { transform: translateY(-100%); opacity: 0; }
  30%  { opacity: 1; }
  100% { transform: translateY(100%); opacity: 0; }
}

/* Hero CTA refinements — premium primary + glass phone */
.hero--home .hero__actions {
  gap: 14px;
  margin-top: 0;
  align-items: center;
}

.hero--home .hero__actions .button {
  min-height: 58px;
  padding: 0 32px;
  font-size: 0.82rem;
  letter-spacing: 0.18em;
  font-weight: 700;
  text-transform: uppercase;
  border-radius: 8px;
}

/* Primary — Request a Quote: brighter aqua gradient */
.hero--home .hero__actions .button--primary {
  background: linear-gradient(135deg, #34c0e0 0%, #1d8fc4 100%);
  color: var(--white);
  border-color: transparent;
  box-shadow:
    0 14px 30px rgba(35, 199, 220, 0.26),
    inset 0 1px 0 rgba(255, 255, 255, 0.24),
    0 0 0 1px rgba(82, 243, 248, 0.22);
}

.hero--home .hero__actions .button--primary:hover,
.hero--home .hero__actions .button--primary:focus {
  background: linear-gradient(135deg, #4fd3ee 0%, #2fa3d5 100%);
  transform: translateY(-2px);
  box-shadow:
    0 20px 42px rgba(35, 199, 220, 0.36),
    inset 0 1px 0 rgba(255, 255, 255, 0.32),
    0 0 0 1px rgba(82, 243, 248, 0.4),
    0 0 38px rgba(82, 243, 248, 0.28);
}

/* Phone button — refined glass tinted secondary */
.hero--home .hero__actions .button--phone {
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(35, 199, 220, 0.42);
  color: var(--brand-blue);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  text-shadow: none;
}

.hero--home .hero__actions .button--phone span:not(.button__icon) {
  color: var(--brand-blue);
  font-weight: 700;
  font-size: 0.98rem;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
}

.hero--home .hero__actions .button--phone .button__icon {
  width: 18px;
  height: 18px;
  margin-right: 10px;
}

.hero--home .hero__actions .button--phone .button__icon--phone::before {
  background: linear-gradient(135deg, var(--brand-aqua) 0%, var(--brand-blue) 100%);
}

.hero--home .hero__actions .button--phone:hover,
.hero--home .hero__actions .button--phone:focus {
  background: rgba(255, 255, 255, 0.92);
  border-color: rgba(35, 199, 220, 0.7);
  transform: translateY(-2px);
  box-shadow:
    0 18px 36px rgba(35, 199, 220, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    0 0 0 1px rgba(82, 243, 248, 0.3);
}

.hero--home .hero__actions .button--phone:hover span:not(.button__icon),
.hero--home .hero__actions .button--phone:focus span:not(.button__icon) {
  color: var(--brand-navy);
}

/* ── REVIEWS / TESTIMONIALS refinements ─────────────────────────── */
.section--reviews-bg .reviews-title {
  font-size: clamp(2.4rem, 5.2vw, 3.6rem);
  letter-spacing: 0.02em;
  font-weight: 500;
  max-width: none;
  margin: 0 auto;
}

/* Reviews section: tighter spacing under "GOOGLE REVIEWS" eyebrow
   before the "Testimonials" headline (the consolidated .section .eyebrow
   rule below provides the full type treatment). Higher specificity
   needed because the general rule appears later in the file. */
.section--reviews-bg .section-intro .eyebrow {
  margin-bottom: 6px;
}

.reviews-rating-script {
  position: relative;
  display: inline-block;
  transform: rotate(-3deg);
  margin: -4px 0 0;
}

.reviews-rating-script::after {
  content: "";
  display: block;
  width: 64%;
  height: 2px;
  background: linear-gradient(90deg, transparent, #e6a91a 30%, #e6a91a 70%, transparent);
  margin: 4px auto 0;
  opacity: 0.6;
}

/* Review count — small subtle label below "Excellent" */
.reviews-count {
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(10, 41, 72, 0.52);
  margin: 14px 0 0;
  text-align: center;
}

.reviews-count strong {
  color: var(--brand-blue);
  font-weight: 700;
  letter-spacing: 0;
  font-size: 0.88rem;
  margin: 0 2px;
}

/* ── PREMIUM TRUST PILLS ────────────────────────────────────────
   Restyle the badge row in the reviews section to feel like the
   hero eyebrow: thin outlined pills, uppercase letter-spaced label,
   aqua icon. Drops the filled gradient + heavy shadow look.       */
.reviews-trust-badges {
  gap: 10px;
  margin: 22px 0 14px;
}

.reviews-trust-badges .trust-badge {
  min-height: 38px;
  padding: 8px 16px 8px 14px;
  gap: 10px;
  background: rgba(255, 255, 255, 0.42);
  border: 1px solid rgba(35, 199, 220, 0.34);
  border-radius: 999px;
  box-shadow: none;
  backdrop-filter: blur(8px) saturate(140%);
  -webkit-backdrop-filter: blur(8px) saturate(140%);
  transition:
    transform 280ms var(--ease-out-quart),
    background 280ms ease,
    border-color 280ms ease,
    box-shadow 280ms ease;
}

.reviews-trust-badges .trust-badge svg {
  width: 14px;
  height: 14px;
  color: var(--brand-aqua);
  stroke-width: 1.6;
  opacity: 1;
  flex-shrink: 0;
}

.reviews-trust-badges .trust-badge__label {
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brand-blue);
  white-space: nowrap;
}

.reviews-trust-badges .trust-badge:hover {
  transform: translateY(-2px);
  background: rgba(255, 255, 255, 0.72);
  border-color: rgba(35, 199, 220, 0.62);
  box-shadow:
    0 12px 28px rgba(35, 199, 220, 0.18),
    0 0 0 1px rgba(82, 243, 248, 0.18);
}

/* ── SECTION INTROS: improved hierarchy ─────────────────────────── */
.home-service-selector .section-intro h2,
.home-trust-section h2,
.process-showcase .section-intro h2 {
  font-size: clamp(1.9rem, 3.2vw, 2.8rem);
  letter-spacing: -0.005em;
  line-height: 1.12;
  font-weight: 700;
}

/* Editorial headline: same large, light-weight, positive-tracked
   treatment as the Testimonials title. Used where a section heading
   should read as a premium statement rather than a label. */
/* Specificity (0,3,1) beats the .home-service-selector .section-intro h2
   rule above (0,2,1) without needing !important. Used on the home
   editorial headline. Weight 500 matches the Testimonials title for a
   consistent crisp heading. */
.home-service-selector .section-intro h2.headline--editorial,
.section-intro h2.headline--editorial,
h2.headline--editorial {
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: clamp(2.4rem, 5.2vw, 3.6rem);
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.08;
  color: var(--ink);
  max-width: none;
  margin: 0 auto;
  text-wrap: balance;
}

/* Editorial-headline accent: slightly darker aqua than the brand
   token so the italic emphasis reads more clearly against the
   pearl canvas without losing the brand colour family. */
.headline--editorial .word--accent {
  color: var(--brand-aqua);
}

/* Process-showcase section: breathing room from the service cards
   above, smaller supporting lead so the headline carries weight. */
.home-service-selector .process-showcase {
  margin-top: clamp(56px, 8vw, 112px);
}

.process-showcase .section-intro .lead {
  font-size: clamp(0.95rem, 1.1vw, 1.05rem);
  line-height: 1.6;
  max-width: 62ch;
  margin-left: auto;
  margin-right: auto;
}

.process-showcase .section-intro .eyebrow,
.home-trust-section .eyebrow,
.section .eyebrow,
.hero--compact .eyebrow,
.quote-intro .eyebrow {
  display: block !important;
  font-size: 0.72rem;
  letter-spacing: 0.32em;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--brand-blue);
  margin-bottom: 14px;
}

/* On photo-backed compact heroes the eyebrow needs to lift off the
   dark overlay. Aqua-light reads better than brand-blue here. */
.hero--compact .eyebrow {
  color: var(--brand-aqua-light, #52f3f8);
}

/* Eyebrow rule above the headline */
.process-showcase .section-intro .eyebrow::before {
  content: "";
  display: inline-block;
  width: 24px;
  height: 1px;
  background: var(--brand-aqua);
  vertical-align: middle;
  margin-right: 12px;
  transform: translateY(-1px);
}

/* ── SERVICE OFFER CARDS: refined chevron + shine sweep on hover ─ */
.offer-card .card__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 700;
  margin-top: 20px;
}

.offer-card .card__body ul + .card__link {
  margin-top: 24px;
}

/* No trailing dash; the link is enough on its own */
.offer-card .card__link::after {
  display: none;
}

/* Aqua glow ring + diagonal shine sweep on hover */
.offer-card--link {
  position: relative;
  isolation: isolate;
}

.offer-card--link::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: var(--radius);
  background: linear-gradient(135deg, rgba(82, 243, 248, 0.0), rgba(82, 243, 248, 0.0));
  z-index: -1;
  opacity: 0;
  transition: opacity 320ms ease;
  pointer-events: none;
}

.offer-card--link:hover::before,
.offer-card--link:focus-visible::before {
  opacity: 1;
  background: radial-gradient(ellipse at top, rgba(82, 243, 248, 0.28), rgba(82, 243, 248, 0));
}

/* Shine sweep across the whole card */
.offer-card--link::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg,
    transparent 38%,
    rgba(255, 255, 255, 0.22) 50%,
    transparent 62%);
  background-size: 250% 100%;
  background-position: 200% 0;
  transition: background-position 900ms var(--ease-out-quart);
  pointer-events: none;
  z-index: 2;
  border-radius: var(--radius);
  mix-blend-mode: overlay;
}

.offer-card--link:hover::after,
.offer-card--link:focus-visible::after {
  background-position: -100% 0;
}

/* Stronger lift + aqua ring on hover (overrides base) */
.offer-card--link:hover,
.offer-card--link:focus-visible {
  transform: translateY(-6px);
  border-color: rgba(35, 199, 220, 0.5);
  box-shadow:
    0 26px 48px rgba(7, 22, 37, 0.14),
    0 0 0 1px rgba(82, 243, 248, 0.22),
    0 0 38px rgba(82, 243, 248, 0.16);
}

/* ── PROCESS SHOWCASE: connecting line + number animation ───────── */
.process-showcase__grid {
  position: relative;
}

@media (min-width: 981px) {
  .process-showcase__grid::before {
    content: "";
    position: absolute;
    left: 7%;
    right: 7%;
    top: 22px;
    height: 1px;
    background:
      repeating-linear-gradient(
        90deg,
        rgba(82, 243, 248, 0.32) 0,
        rgba(82, 243, 248, 0.32) 4px,
        transparent 4px,
        transparent 10px
      );
    z-index: 0;
    pointer-events: none;
    mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  }
}

.process-showcase__card {
  z-index: 1;
  transition:
    transform 420ms var(--ease-out-quart),
    box-shadow 420ms var(--ease-out-quart),
    border-color 420ms ease;
}

.process-showcase__card:hover {
  transform: translateY(-5px);
  border-top-color: var(--brand-aqua-light);
  box-shadow:
    0 24px 48px rgba(7, 22, 37, 0.34),
    0 0 0 1px rgba(82, 243, 248, 0.28),
    0 0 38px rgba(82, 243, 248, 0.16);
}

.process-showcase__card:hover .process-showcase__num {
  color: rgba(82, 243, 248, 0.20);
}

.process-showcase__card:hover .process-showcase__icon {
  transform: rotate(-8deg) scale(1.08);
}

.process-showcase__card:hover .process-showcase__icon svg {
  stroke: var(--brand-aqua-light);
}

.process-showcase__num {
  font-family: "Montserrat", sans-serif;
  font-weight: 900;
  color: rgba(82, 243, 248, 0.07);
  font-size: 110px;
  bottom: -12px;
  letter-spacing: -6px;
  transition: color 600ms ease;
}

.process-showcase__icon {
  position: relative;
  background:
    radial-gradient(circle at 30% 30%, rgba(82, 243, 248, 0.22), transparent 70%),
    rgba(255, 255, 255, 0.05);
  box-shadow:
    inset 0 0 0 1px rgba(82, 243, 248, 0.24),
    0 0 22px rgba(82, 243, 248, 0.08);
  transition: transform 420ms var(--ease-out-quart);
}

.process-showcase__icon svg {
  transition: stroke 420ms ease;
}

.process-showcase__card h3 {
  font-size: 1.1rem;
  letter-spacing: 0.01em;
  margin-bottom: 8px;
}

/* ── TRUST SECTION: refined feature list ────────────────────────── */
/* ── HOME TRUST SECTION (section--dark on light canvas) ─────────
   The styles.css canvas override at line 4029 strips section--dark
   background but misses .lead and .feature p — they still get the
   original white-on-dark text colors. Restore proper contrast.   */
.section--dark .lead,
.section--green .lead {
  color: var(--muted);
}

.section--dark .feature p,
.section--green .feature p {
  color: var(--muted);
}

/* ── CTA band text contrast on dark/green sections ─────────────────
   .cta-band has its own dark-navy gradient (set in styles.css).
   When it sits in a .section--dark or .section--green, the inherited
   styles.css colors and the broad .section .eyebrow rule render the
   headline + lead near-black on the dark gradient. Force light text
   contrast — but scope strictly to .cta-band so the home trust
   section (which carries section--dark but renders on the light
   canvas) is unaffected. */
.section--dark .cta-band,
.section--green .cta-band {
  color: rgba(255, 255, 255, 0.92);
}

.section--dark .cta-band .eyebrow,
.section--green .cta-band .eyebrow {
  color: var(--brand-aqua-light, #52f3f8) !important;
}

.section--dark .cta-band h1,
.section--dark .cta-band h2,
.section--dark .cta-band h3,
.section--green .cta-band h1,
.section--green .cta-band h2,
.section--green .cta-band h3 {
  color: #fff;
}

.section--dark .cta-band p,
.section--green .cta-band p {
  color: rgba(255, 255, 255, 0.82);
}

.home-trust-section .feature {
  padding: 4px 0 4px 22px;
}

.home-trust-section .feature h3 {
  font-size: 1.05rem;
  letter-spacing: 0.01em;
  margin-bottom: 6px;
}

.home-trust-section .feature p {
  font-size: 0.96rem;
  line-height: 1.55;
}

/* ─── Editorial feature list (overrides the styles.css left-bar) ───
   Remove the heavy left bar. Replace with a small aqua dash before
   each h3, generous vertical rhythm, body indented to align with
   the h3 label (not the dash). Reads as airy editorial copy.       */
.home-trust-section .feature-list,
.section .feature-list {
  gap: 28px;
}

.home-trust-section .feature,
.section .feature {
  padding: 0 !important;
  border: 0 !important;
  background: transparent !important;
}

.home-trust-section .feature::before,
.section .feature::before {
  display: none !important;
}

.home-trust-section .feature h3,
.section .feature h3 {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.005em;
  color: var(--brand-navy);
  margin-bottom: 8px;
}

.home-trust-section .feature h3::before,
.section .feature h3::before {
  content: "";
  flex-shrink: 0;
  width: 18px;
  height: 2px;
  background: var(--brand-aqua);
  border-radius: 2px;
}

.home-trust-section .feature p,
.section .feature p {
  font-size: 0.96rem;
  line-height: 1.65;
  margin: 0;
  padding-left: 32px;
  color: var(--muted);
  max-width: 56ch;
}

.home-trust-section .feature .trust-badges,
.section .feature .trust-badges {
  padding-left: 32px;
  margin-top: 4px;
}

/* Media block caption — refined */
.media-block__caption {
  background: linear-gradient(180deg, rgba(7, 22, 37, 0.58), rgba(7, 22, 37, 0.88));
  border-color: rgba(255, 255, 255, 0.08);
  padding: 18px 20px;
}

.media-block__caption strong {
  display: block;
  font-family: "Montserrat", sans-serif;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  margin-bottom: 4px;
}

.media-block__caption p {
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.78);
  line-height: 1.5;
}

/* Image subtle zoom on hover for media blocks */
.media-block {
  overflow: hidden;
}

.media-block img {
  transition: transform 1400ms var(--ease-out-quart);
  will-change: transform;
}

.media-block:hover img {
  transform: scale(1.035);
}

/* ── TASK 8: tall dominant media-block on soft service pages ────────
   window-cleaning + house-washing media-block section. Tall frame only:
   left text/4-card column ratios stay the default .split values; we only
   switch this variant to stretch and raise the media-block min-height so
   the portrait reads as a dominant element, not a small side panel.
   object-fit:cover + the hover-zoom above + the caption stay intact. */
.split--media-tall {
  align-items: stretch;
}

.split--media-tall .media-block {
  align-self: stretch;
  min-height: clamp(460px, 52vw, 640px);
}

/* Mobile guard: page is stacked at <=980px; at <=640px cap the height so
   the clamp floor (460px) doesn't make the stacked portrait excessive. */
@media (max-width: 640px) {
  .split--media-tall .media-block {
    min-height: 400px;
  }
}

/* ── CTA BAND: animated shimmer ─────────────────────────────────── */
.cta-band {
  padding: clamp(34px, 5vw, 56px);
}

/* Align the CTA band's internal house watermark with the .watermark-
   section's bottom-right anchored background watermark (only on pages
   that wrap their CTA in .section.section--green.watermark-section, e.g.
   pre-sale-exterior-reset, about, maintenance-plans). Home page CTA sits
   in .section.section--paper with a different bg system and keeps the
   original styles.css positioning. */
.watermark-section .cta-band::before {
  right: clamp(-220px, -16vw, -130px);
  top: 70%;
}

.cta-band::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(115deg,
      transparent 0%,
      transparent 40%,
      rgba(82, 243, 248, 0.10) 50%,
      transparent 60%,
      transparent 100%);
  background-size: 300% 100%;
  animation: shimmer-sweep 8s linear infinite;
  pointer-events: none;
  z-index: 0;
}

@keyframes shimmer-sweep {
  0%   { background-position: 200% 0; }
  100% { background-position: -100% 0; }
}

.cta-band h2 {
  font-size: clamp(1.7rem, 3vw, 2.4rem);
  letter-spacing: -0.005em;
}

.cta-band .button {
  min-height: 56px;
  padding: 0 32px;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
}

.cta-band .button--copper {
  background: linear-gradient(135deg, var(--brand-aqua-light), var(--brand-aqua));
  color: var(--brand-navy);
  font-weight: 800;
  box-shadow:
    0 16px 32px rgba(35, 199, 220, 0.32),
    0 0 0 1px rgba(255, 255, 255, 0.18);
}

.cta-band .button--copper:hover,
.cta-band .button--copper:focus {
  background: linear-gradient(135deg, #b3f8fb, #52f3f8);
  transform: translateY(-2px);
  box-shadow:
    0 22px 38px rgba(35, 199, 220, 0.4),
    0 0 0 1px rgba(255, 255, 255, 0.3);
}

/* ── HERO: keep the light canvas treatment from styles.css ──────── */
/* No fallback color here — let the body's light pearl background
   show through the hero so the hero feels airy, not boxed-in.     */

/* ── MOBILE STICKY CTA BAR ─────────────────────────────────────── */
.mobile-cta-bar {
  display: none;
}

@media (max-width: 980px) {
  .mobile-cta-bar {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 8px;
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: 12px;
    z-index: 30;
    padding: 8px;
    border-radius: 18px;
    background: rgba(255, 255, 255, 0.72);
    backdrop-filter: blur(22px) saturate(180%);
    -webkit-backdrop-filter: blur(22px) saturate(180%);
    box-shadow:
      0 20px 44px rgba(7, 22, 37, 0.18),
      inset 0 1px 0 rgba(255, 255, 255, 0.7),
      0 0 0 1px rgba(35, 199, 220, 0.22);
    transform: translateY(140%);
    transition: transform 420ms var(--ease-out-quart);
  }

  .mobile-cta-bar.is-visible {
    transform: translateY(0);
  }

  /* Isolated CTA component — does NOT inherit from .button */
  .m-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 50px;
    padding: 0 22px;
    border-radius: 12px;
    font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    border: 1px solid transparent;
    transition: transform 180ms ease, background 200ms ease, box-shadow 200ms ease;
    -webkit-tap-highlight-color: transparent;
    -webkit-font-smoothing: antialiased;
  }

  .m-cta__icon,
  .m-cta__chev {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
  }

  .m-cta__label {
    line-height: 1;
  }

  /* Ghost (Call) — light glass with brand-blue text */
  .m-cta--ghost {
    background: rgba(255, 255, 255, 0.6);
    color: var(--brand-blue);
    border-color: rgba(35, 199, 220, 0.36);
    padding: 0 16px;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
  }

  .m-cta--ghost .m-cta__icon {
    color: var(--brand-aqua);
  }

  .m-cta--ghost:active {
    background: rgba(255, 255, 255, 0.92);
    transform: scale(0.97);
  }

  /* Primary (Request Quote) — aqua→blue brand gradient with white text */
  .m-cta--primary {
    background: linear-gradient(135deg, #34c0e0 0%, #1d8fc4 100%);
    color: var(--white);
    border-color: transparent;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.32),
      0 8px 18px rgba(35, 199, 220, 0.28);
  }

  .m-cta--primary .m-cta__chev {
    transition: transform 220ms var(--ease-out-quart);
    opacity: 0.92;
  }

  .m-cta--primary:active {
    transform: scale(0.97);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.32),
      0 4px 12px rgba(35, 199, 220, 0.32);
  }

  .m-cta--primary:active .m-cta__chev {
    transform: translateX(3px);
  }

  main {
    padding-bottom: 80px;
  }

  /* Hero spacing on mobile */
  .hero--home {
    min-height: 78vh;
    padding-top: calc(var(--header-height) + 56px);
    padding-bottom: 32px;
  }

  .hero__scroll-cue {
    display: none;
  }

  .hero__eyebrow {
    font-size: 0.62rem;
    letter-spacing: 0.28em;
    gap: 8px;
  }

  .hero__eyebrow::before,
  .hero__eyebrow::after {
    width: 18px;
  }

  .hero--home h1 {
    font-size: clamp(2.2rem, 9vw, 3.4rem);
    letter-spacing: 0.01em;
  }

  /* Locations: drop letter-spacing, use bullets */
  .hero--home .hero__locations {
    font-size: 0.7rem;
    letter-spacing: 0.24em;
    gap: 10px;
    flex-wrap: wrap;
    justify-content: center;
  }

  /* Mobile menu: smoother transition */
  .main-nav {
    transition: opacity 240ms ease;
    opacity: 0;
  }

  .main-nav.is-open {
    opacity: 1;
  }

  /* Process showcase mobile — drop connecting line */
  .process-showcase__grid::before {
    display: none;
  }

  /* Service offer cards — tighter mobile  */
  .home-service-selector .grid--4 {
    gap: 12px;
  }
}

/* Reduced-motion overrides are consolidated at the bottom of this file
   (see "Reduced motion: disable all motion the polish layer adds"). */

/* ── SECTION-INTRO CENTERED: better mobile padding ─────────────── */
.section-intro--centered .lead {
  font-size: clamp(1rem, 1.5vw, 1.16rem);
  line-height: 1.6;
  color: var(--muted);
}

/* ── FOOTER: refined ────────────────────────────────────────────── */
.footer h3 {
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brand-aqua-light);
  font-weight: 600;
  margin-bottom: 16px;
}

.footer p,
.footer li {
  font-size: 0.92rem;
  line-height: 1.7;
}

.footer a {
  transition: color 200ms ease;
}

.footer__bottom {
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.42);
}

/* ── AREAS / LOCATION pages: page-top hero breathing room ────────
   .section--areas-map is the page's hero on areas.html and every
   location page (yamba, maclean, grafton, brooms-head, iluka).
   The fixed site-header is ~83px tall; the old clamp(32,5vh,56)
   top padding left the H1 sitting under (and partly behind) the
   header. Match the styles.css clamp(128,13vw,188) so the heading
   clears the header with comfortable breathing room. Keep the
   tightened bottom padding so the location cards stay near the
   fold. */
.section--areas-map {
  padding-top: clamp(128px, 13vw, 188px) !important;
  padding-bottom: clamp(40px, 6vh, 72px) !important;
  position: relative;
  overflow: hidden;
}

/* ── AREAS / LOCATION pages: site-matching watermark ─────────────
   Give the area-page hero the SAME large, faint, right-side BCE
   icon watermark as .hero--home::after on the homepage, instead of
   the tiny centred .section-intro--brand-watermark::after (which was
   set to opacity 0.03 and effectively invisible). The section is
   position:relative + overflow:hidden above, so this ::after anchors
   to the section and the oversized mark is clipped to it.
   z-index:0 keeps the mark ABOVE the section's (transparent) bg but
   BELOW the .container (which styles.css sets to z-index:1) so all
   text and cards sit on top. Values mirror .hero--home::after. */
.section--areas-map::after,
.results-hero::after {
  content: "";
  position: fixed;
  inset: 0;
  background-image: var(--watermark-image);
  background-repeat: no-repeat;
  background-position: right clamp(72px, 9vw, 180px) center;
  background-size: clamp(520px, 35vw, 680px);
  opacity: 0.08;
  pointer-events: none;
  z-index: 0;
}

@media (min-width: 981px) {
  .section--areas-map::after,
  .results-hero::after {
    background-size: clamp(760px, 44vw, 920px);
  }
}

/* Only one watermark on area pages: kill the small centred one that
   ships on .section-intro--brand-watermark inside this section. */
.section--areas-map .section-intro--brand-watermark::after {
  display: none;
}

/* Hero-style time-based entrance for the section-intro on location
   pages — matches the hero--home cascade pattern (eyebrow → H1).
   Higher specificity than styles.css `.section-intro > .eyebrow`
   (0,2,1) so this overrides its scroll-timeline animation. */
.section--areas-map .section-intro > .eyebrow {
  opacity: 0;
  animation: fade-up-in 1300ms var(--ease-out-quart) 250ms forwards;
  animation-timeline: auto;
  animation-range: normal;
}

.section--areas-map .section-intro h1 {
  opacity: 0;
  animation: fade-up-in 1400ms var(--ease-out-quart) 700ms forwards;
  animation-timeline: auto;
  animation-range: normal;
}

.section--areas-map .section-intro.stack > p.lead {
  opacity: 0;
  animation: fade-up-in 1200ms var(--ease-out-quart) 900ms forwards;
  animation-timeline: auto;
  animation-range: normal;
  color: var(--charcoal); /* #102a3d — crisp on the light area hero */
}

/* Request-Quote page hero (quote-intro layout, not hero--home).
   Mirror the time-based cascade so the eyebrow + H1 enter on load. */
.quote-intro .eyebrow {
  opacity: 0;
  animation: fade-up-in 1300ms var(--ease-out-quart) 250ms forwards;
}

.quote-intro h1 {
  opacity: 0;
  animation: fade-up-in 1400ms var(--ease-out-quart) 700ms forwards;
}

.quote-intro .lead {
  opacity: 0;
  animation: fade-up-in 1200ms var(--ease-out-quart) 900ms forwards;
  animation-timeline: auto;
  animation-range: normal;
}

@media (prefers-reduced-motion: reduce) {
  .section--areas-map .section-intro.stack > p.lead,
  .quote-intro.stack > p.lead { opacity: 1; animation: none; filter: none; }
}

@media (prefers-reduced-motion: no-preference) {
  /* The generic `.section .stack > p.lead` scroll-driven rule (0,3,1) in
     styles.css outranks `.quote-intro .lead` and leaves the request-quote
     subtitle part-faded at narrow viewport heights. Re-assert the
     time-based reveal at matching specificity (wins by source order). */
  .quote-intro.stack > p.lead {
    animation: fade-up-in 1200ms var(--ease-out-quart) 900ms forwards;
    animation-timeline: auto;
    animation-range: normal;
  }
}

.section--areas-map .container.stack {
  gap: clamp(20px, 3vh, 32px);
}

.section--areas-map .section-intro {
  margin-bottom: 0;
}

.section--areas-map .section-intro h1 {
  margin-top: 4px;
  margin-bottom: 0;
}

/* =====================================================
   SCROLL-DRIVEN ANIMATION EXPANSION  v20260524-1
   Extends the @supports block in styles.css to cover
   every remaining content segment site-wide.

   Keyframe reused from styles.css:
     content-scroll  — fade-up-in · hold · fade-up-out
     pill-fade       — opacity only (no translate)

   Specificity note for elements with data-stagger:
     [data-stagger].has-entered > *  = (0,2,0)
     .grid.process > .card           = (0,2,1)  wins ✓
   ===================================================== */

@supports (animation-timeline: view()) {

  /* ── Shorthand variable (applied to every rule below)
        animation-timing-function : linear
        animation-fill-mode       : both
        animation-timeline        : view()
        animation-duration        : auto              */

  /* @keyframes used by the comparison wrapper below */
  @keyframes fade-in-hold {
    0%  { opacity: 0; translate: 0 40px; }
    30% { opacity: 1; translate: 0 0;    }
    100% { opacity: 1; translate: 0 0;   }
  }

  /* Shared animation properties for every scroll-driven content
     element. Keep selectors here at their normal specificity so the
     per-element nth-child animation-range overrides further down can
     win without :where()-related cascade surprises. */
  .grid.process > .card,
  .process-showcase__grid > .process-showcase__card,
  .grid--2 > .card,
  .grid--2 > .info-card,
  .grid--4 > .service-card,
  .home-service-selector .grid--4[data-stagger] > *,
  .media-block:not(.media-block--comparison),
  .feature-list > .feature,
  .table-row,
  .about-highlight,
  .gallery-card,
  .location-card,
  .area-highlight,
  .grid.grid--3[data-stagger] > *,
  .mock-report,
  .documentation__uses li,
  .documentation__pricing {
    animation-name: content-scroll;
    animation-timing-function: linear;
    animation-fill-mode: both;
    animation-timeline: view();
    animation-duration: auto;
  }

  /* Comparison wrapper uses a different keyframe (entry-only hold so
     the internal slider isn't hidden mid-use). */
  .media-block--comparison {
    animation-name: fade-in-hold;
    animation-timing-function: linear;
    animation-fill-mode: both;
    animation-timeline: view();
    animation-duration: auto;
    animation-range: cover 0% cover 80%;
  }

  /* Default range per element family (overridden per nth-child below
     for staggered grids). Most scroll a full 100% of cover; media /
     features / tables exit slightly earlier (95%); area highlights
     even earlier (90%) so the map iframe isn't faded mid-scroll. */
  .grid.process > .card,
  .process-showcase__grid > .process-showcase__card,
  .grid--2 > .card,
  .grid--2 > .info-card,
  .grid--4 > .service-card,
  .home-service-selector .grid--4[data-stagger] > *,
  .about-highlight,
  .gallery-card,
  .location-card,
  .grid.grid--3[data-stagger] > *,
  .mock-report,
  .documentation__pricing {
    animation-range: cover 0% cover 100%;
  }

  /* Documentation use-cases — stagger each bullet by a small range
     so they roll up sequentially as the band enters. */
  .documentation__uses li:nth-child(1) { animation-range: cover  5% cover 100%; }
  .documentation__uses li:nth-child(2) { animation-range: cover 10% cover 100%; }
  .documentation__uses li:nth-child(3) { animation-range: cover 15% cover 100%; }

  .media-block:not(.media-block--comparison),
  .feature-list > .feature,
  .table-row {
    animation-range: cover 0% cover 95%;
  }

  .area-highlight {
    animation-range: cover 0% cover 90%;
  }

  /* Per-element stagger overrides — each card starts slightly later
     than its left neighbour, creating a cascade as the section rolls
     into the viewport. */

  /* 4-step process (home + service pages) */
  .grid.process > .card:nth-child(2),
  .process-showcase__grid > .process-showcase__card:nth-child(2) { animation-range: cover  8% cover 100%; }
  .grid.process > .card:nth-child(3),
  .process-showcase__grid > .process-showcase__card:nth-child(3) { animation-range: cover 16% cover 100%; }
  .grid.process > .card:nth-child(4),
  .process-showcase__grid > .process-showcase__card:nth-child(4) { animation-range: cover 24% cover 100%; }

  /* 2-col info-card grids (service pages) */
  .grid--2 > .card:nth-child(2),
  .grid--2 > .info-card:nth-child(2) { animation-range: cover 7% cover 100%; }

  /* 4-col area service cards */
  .grid--4 > .service-card:nth-child(2) { animation-range: cover  8% cover 100%; }
  .grid--4 > .service-card:nth-child(3) { animation-range: cover 16% cover 100%; }
  .grid--4 > .service-card:nth-child(4) { animation-range: cover 24% cover 100%; }

  /* Home offer cards (Presentation / House Washing / Window Cleaning /
     Pressure Cleaning) — left-to-right stagger matching the process
     and area-service cards. */
  .home-service-selector .grid--4[data-stagger] > *:nth-child(2) { animation-range: cover  8% cover 100%; }
  .home-service-selector .grid--4[data-stagger] > *:nth-child(3) { animation-range: cover 16% cover 100%; }
  .home-service-selector .grid--4[data-stagger] > *:nth-child(4) { animation-range: cover 24% cover 100%; }

  /* About-page 4-item icon-label grid */
  .about-highlight:nth-child(2) { animation-range: cover  7% cover 100%; }
  .about-highlight:nth-child(3) { animation-range: cover 14% cover 100%; }
  .about-highlight:nth-child(4) { animation-range: cover 21% cover 100%; }

  /* Case-studies gallery cards */
  .gallery-card:nth-child(2) { animation-range: cover  6% cover 100%; }
  .gallery-card:nth-child(3) { animation-range: cover 12% cover 100%; }
  .gallery-card:nth-child(4) { animation-range: cover 18% cover 100%; }

  /* Areas overview location cards */
  .location-card:nth-child(2) { animation-range: cover  8% cover 100%; }
  .location-card:nth-child(3) { animation-range: cover 16% cover 100%; }

  /* 3-col data-stagger grids (about, commercial, pre-sale, maintenance).
     Specificity (0,3,0) wins over the [data-stagger].has-entered
     selector from styles.css; the nth-child range overrides below
     are (0,4,0) and win cleanly. */
  .grid.grid--3[data-stagger] > *:nth-child(2) { animation-range: cover  7% cover 100%; }
  .grid.grid--3[data-stagger] > *:nth-child(3) { animation-range: cover 14% cover 100%; }
  .grid.grid--3[data-stagger] > *:nth-child(4) { animation-range: cover 21% cover 100%; }
  .grid.grid--3[data-stagger] > *:nth-child(5) { animation-range: cover 28% cover 100%; }
  .grid.grid--3[data-stagger] > *:nth-child(6) { animation-range: cover 35% cover 100%; }

  /* "Presented not thrown" — soften the scroll-driven keyframes that
     ship from styles.css. The original 90px/80px translate distances
     read as a lurch as elements enter and exit; halving them keeps
     the cascade legible but feels like content settling into place.
     Also widen the in-view dwell so each block reads before fading
     out (32-68% → 28-72%). */
  @keyframes content-scroll {
    0%   { opacity: 0; translate: 0 40px; }
    28%  { opacity: 1; translate: 0 0;    }
    72%  { opacity: 1; translate: 0 0;    }
    100% { opacity: 0; translate: 0 -32px; }
  }

  /* Hero exits less abruptly on first scroll past the fold. */
  @keyframes hero-content-exit {
    from { opacity: 1; translate: 0 0;    }
    to   { opacity: 0; translate: 0 -28px; }
  }

}

/* ── Reduced motion: disable all motion the polish layer adds ──── */
@media (prefers-reduced-motion: reduce) {
  /* Hero entrance + scroll-out animations */
  .hero-h1-reveal,
  .hero__eyebrow,
  .hero--home .lead,
  .hero--home .hero__locations,
  .hero--home .hero__actions,
  .hero__scroll-cue {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    animation: none !important;
  }
  .cta-band::after,
  .hero__scroll-cue__bar::after { animation: none; }

  /* Scroll-driven content reveals across the rest of the site */
  .grid.process > .card,
  .process-showcase__grid > .process-showcase__card,
  .grid--2 > .card,
  .grid--2 > .info-card,
  .grid--4 > .service-card,
  .media-block:not(.media-block--comparison),
  .media-block--comparison,
  .feature-list > .feature,
  .table-row,
  .about-highlight,
  .gallery-card,
  .location-card,
  .area-highlight,
  .grid.grid--3[data-stagger] > * {
    animation: none;
    opacity: 1;
    translate: none;
  }
}


/* Generic .word--accent (any hero or heading) — italic Montserrat aqua.
   Scoped .hero--home rule above retains its own letter-spacing/weight. */
.word--accent {
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-style: italic;
  font-weight: 600;
  color: var(--brand-aqua);
}


/* Before/after slider (rotating drag comparisons) */
/* width:100% is load-bearing: without an explicit width the block
   shrink-wraps to the comparison's intrinsic (aspect-ratio-derived)
   width, collapsing the slider to ~237px and never reaching max-width.
   With width:100% it fills the column up to max-width and the
   comparison's aspect-ratio then derives height FROM the width. */
.ba-slider { width: 100%; max-width: 440px; margin: 0 auto; }
.ba-slider__viewport { position: relative; }
.ba-slide { position: absolute; inset: 0; opacity: 0; visibility: hidden; transition: opacity 600ms var(--ease-out-quart); }
.ba-slide.is-active { position: relative; opacity: 1; visibility: visible; }
.ba-slider .comparison--feature { aspect-ratio: 4 / 5; }
.ba-slide__caption { margin: 12px 0 0; text-align: center; color: var(--muted); font-size: 0.95rem; }
.ba-slider__dots { display: flex; justify-content: center; gap: 4px; margin-top: 12px; }
.ba-slider__dot { width: 24px; height: 24px; padding: 0; border: 0; background: transparent; cursor: pointer; position: relative; }
.ba-slider__dot::before { content: ""; position: absolute; inset: 0; margin: auto; width: 9px; height: 9px; border-radius: 50%; background: rgba(10,41,72,0.22); transition: background 200ms ease, transform 200ms ease; }
.ba-slider__dot.is-active::before { background: var(--brand-aqua); transform: scale(1.25); }
@media (prefers-reduced-motion: reduce) { .ba-slide { transition: none; } }

/* ── Merged proof section: reviews ride the before/after slider ───────────────
   Light (paper) background — the slider photos + dark quote box give the
   contrast; floating before/after thumbnails sit behind as accents. */
.reviews-merged {
  position: relative;
  overflow: hidden;
}
.reviews-merged .reviews-bg__content { gap: clamp(18px, 2.4vw, 30px); position: relative; z-index: 2; }
.reviews-merged .section-intro { margin-bottom: 0; }
/* Keep the wide centred intro so the 4-pill row doesn't clip. */
.reviews-merged .section-intro--centered { width: min(1080px, 100%); }
.reviews-merged .reviews-proof-lead {
  color: var(--muted);
  max-width: 56ch;
  margin-inline: auto;
}

/* Compact Google rating badge — light variant, centred on its own line. */
.google-rating-badge {
  display: flex;
  width: max-content;
  max-width: 100%;
  margin: 4px auto 0;
  align-items: center;
  gap: 9px;
  padding: 8px 16px;
  border-radius: 999px;
  background: rgba(10,41,72,0.05);
  border: 1px solid rgba(10,41,72,0.16);
  color: var(--ink);
  text-decoration: none;
  font-weight: 500;
  font-size: 0.92rem;
  transition: background 180ms ease, border-color 180ms ease, transform 180ms ease;
}
.google-rating-badge:hover,
.google-rating-badge:focus-visible {
  background: rgba(10,41,72,0.09);
  border-color: rgba(10,41,72,0.28);
  transform: translateY(-1px);
}
.google-rating-badge__g { width: 18px; height: 18px; display: inline-flex; }
.google-rating-badge__g svg { width: 100%; height: 100%; }
.google-rating-badge__stars { color: #f4b400; letter-spacing: 1px; }
.google-rating-badge__text strong { font-weight: 800; }

/* Floating before/after thumbnails flanking the slider in the proof section.
   Big and pulled in toward the slider; gated to wide screens so they don't
   crowd the slider on smaller desktops. */
.proof-photos { display: none; }
@media (min-width: 1100px) {
  .proof-photos {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
  }
  .proof-photo {
    position: absolute;
    width: clamp(210px, 17.5vw, 310px);
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 22px 50px rgba(10, 41, 72, 0.18);
    opacity: 0.65;
  }
  .proof-photo img {
    display: block; width: 100%; height: 100%;
    aspect-ratio: 4 / 5; object-fit: cover; filter: saturate(0.95);
  }
  .proof-photo--tl { top: 33%;   left: 4.5%; }
  .proof-photo--bl { bottom: 6%;  left: 7.5%; }
  .proof-photo--tr { top: 35%;   right: 4.5%; }
  .proof-photo--br { bottom: 6%;  right: 7.5%; }
}

/* ── Hero review collage: scattered Google-review quote cards in the hero at
   varied sizes/angles. Decorative (aria-hidden; the real reviews live in the
   proof section), pointer-events:none, behind the headline. Desktop only. */
/* ── Review artifacts: real Google-review cards scattered down the page,
   surfacing on scroll. Decorative (aria-hidden; the real reviews live in the
   proof section). Transparent frosted glass, clear (frosted) text. Desktop. */
main { position: relative; }
.page-artifacts { display: none; }
@media (min-width: 1100px) {
  .page-artifacts { display: block; position: absolute; inset: 0; z-index: 5; pointer-events: none; overflow: clip; }
  /* Premium frosted review chip. Default = light glass for the pale "paper"
     sections; .review-artifact--on-dark flips it for the dark band and photos.
     Per-card width + angle live in the position rules below, so the chips read
     as a varied, hand-placed set rather than a uniform run. */
  .review-artifact {
    position: absolute;
    margin: 0;
    width: 208px;
    padding: 13px 16px 12px;
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.80);
    border: 1px solid rgba(7, 22, 37, 0.07);
    backdrop-filter: blur(16px) saturate(1.1);
    -webkit-backdrop-filter: blur(16px) saturate(1.1);
    color: var(--ink);
    box-shadow: 0 14px 30px rgba(10, 41, 72, 0.13), 0 3px 8px rgba(10, 41, 72, 0.07);
    opacity: 0;
    transition: opacity 700ms var(--ease-out-quart);
  }
  .review-artifact.is-visible { opacity: 1; }
  .review-artifact blockquote { margin: 0 0 9px; line-height: 1.42; font-size: 0.92rem; font-weight: 500; color: #1d3a52; text-wrap: balance; }
  .review-artifact figcaption { display: flex; align-items: center; gap: 6px; font-size: 0.72rem; color: rgba(21, 50, 74, 0.6); }
  .review-artifact__name { font-weight: 700; color: var(--ink); }
  .review-artifact__src { display: inline-flex; align-items: center; gap: 5px; }
  /* Dark variant: dark band + over photos (keeps white text legible). */
  .review-artifact--on-dark {
    background: linear-gradient(180deg, rgba(7, 22, 37, 0.50) 0%, rgba(7, 22, 37, 0.66) 100%);
    border: 1px solid rgba(255, 255, 255, 0.14);
    color: #fff;
    box-shadow: 0 18px 40px rgba(7, 22, 37, 0.30);
  }
  .review-artifact--on-dark blockquote { color: #fff; text-shadow: 0 1px 8px rgba(7, 22, 37, 0.55); }
  .review-artifact--on-dark figcaption { color: rgba(255, 255, 255, 0.82); }
  .review-artifact--on-dark .review-artifact__name { color: #fff; }
  .review-artifact__src::before {
    content: "";
    width: 12px; height: 12px; flex: 0 0 auto;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath fill='%234285F4' d='M45.12 24.5c0-1.56-.14-3.06-.4-4.5H24v8.51h11.84c-.51 2.75-2.06 5.08-4.39 6.64v5.52h7.11c4.16-3.83 6.56-9.47 6.56-16.17z'/%3E%3Cpath fill='%2334A853' d='M24 46c5.94 0 10.92-1.97 14.56-5.33l-7.11-5.52c-1.97 1.32-4.49 2.1-7.45 2.1-5.73 0-10.58-3.87-12.31-9.07H4.34v5.7C7.96 41.07 15.4 46 24 46z'/%3E%3Cpath fill='%23FBBC05' d='M11.69 28.18C11.25 26.86 11 25.45 11 24s.25-2.86.69-4.18v-5.7H4.34C2.85 17.09 2 20.45 2 24s.85 6.91 2.34 9.88l7.35-5.7z'/%3E%3Cpath fill='%23EA4335' d='M24 10.75c3.23 0 6.13 1.11 8.41 3.29l6.31-6.31C34.91 4.18 29.93 2 24 2 15.4 2 7.96 6.93 4.34 14.12l7.35 5.7c1.73-5.2 6.58-9.07 12.31-9.07z'/%3E%3C/svg%3E") no-repeat center / contain;
  }

  /* Hero chips anchor to the TOP (they live inside the vh-sized hero). Every
     other chip anchors to the BOTTOM of main: everything below the hero is
     fixed-height, so bottom-anchoring keeps them put regardless of viewport
     HEIGHT (the hero is 100vh + 18vh, so top-anchoring would drift them as the
     window height changes). Horizontal stays in % to clear the centred columns.
     Widths/angles vary deliberately so the set reads hand-placed, not uniform. */
  .review-artifact--a { top: 150px;     left: 4%;    width: 196px; transform: rotate(-3deg); } /* hero upper-left */
  .review-artifact--d { top: 470px;     right: 6%;   width: 184px; transform: rotate(2deg); }  /* hero right */
  .review-artifact--h { bottom: 5357px; left: 8%;    width: 198px; transform: rotate(-3deg); } /* reviews: left mid-gap between proof photos (Lynda) */
  .review-artifact--f { bottom: 5344px; right: 8%;   width: 226px; transform: rotate(-2deg); } /* reviews: right mid-gap between proof photos (Sharon) */
  .review-artifact--g { bottom: 4222px; left: 8%;    width: 236px; transform: rotate(3deg); }  /* services: gap below offer cards, left (Adam) */
  .review-artifact--e { bottom: 4126px; right: 8%;   width: 188px; transform: rotate(-2deg); } /* services: gap below offer cards, right (Belinda) */
  .review-artifact--c { bottom: 1744px; left: 9%;    width: 216px; transform: rotate(2deg); }  /* dark trust: clean gap below copy, on-dark (Ann-Marie) */
  .review-artifact--i { bottom: 1342px; left: 19%;   width: 202px; transform: rotate(3deg); }  /* meet-owner: roof-photo sky, on-dark (Angelo) */
  .review-artifact--b { bottom: 574px;  right: 12%;  width: 204px; transform: rotate(-2deg); } /* meet-owner: right column gap below About button (Anne) */
  .review-artifact--j { bottom: 369px;  left: 58%;   width: 184px; transform: rotate(2deg); }  /* CTA: whitespace above the band (Lea) */
}
/* Width-sensitive chips: as the viewport narrows, the centred service heading
   and the CTA band widen toward these positions, and the hero H1 reaches the
   corner chips, so these only show once there is room (>=1400px). The other
   five (b, c, f, h, i) sit over imagery or large gaps and stay clean from
   1100px. */
@media (max-width: 1400px) {
  .review-artifact--a,
  .review-artifact--d,
  .review-artifact--e,
  .review-artifact--g,
  .review-artifact--j { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .review-artifact { transition: none; }
}

/* Slider is the dominant centrepiece on desktop. Phone keeps basic 440px. */
@media (min-width: 981px) {
  .ba-slider--quotes { max-width: min(800px, 58vw); }
}

/* Spacing pass: separate the service cards ("Designed to protect your asset")
   from the "Why choose Be Clean Exteriors" process block so each reads as its
   own stanza instead of one cramped stack. */
.home-service-selector .process-showcase { margin-top: clamp(32px, 5.5vw, 72px); }

/* ── Quote overlay (HOME ONLY via .ba-slider--quotes) ─────────────────────────
   A bottom glass band anchored INSIDE the image box so it works even when the
   slider is taller than the viewport. pointer-events:none so drags fall through
   to [data-comparison] (only the comparison captures pointers, not .ba-slider). */
.ba-slider--quotes .ba-slide__caption { display: none; } /* the quote owns the bottom now */
.ba-quotes {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}
.ba-quote {
  position: absolute;
  left: clamp(12px, 2.2vw, 24px);
  right: clamp(12px, 2.2vw, 24px);
  bottom: clamp(12px, 2.2vw, 24px);
  margin: 0;
  padding: 16px 18px 14px;
  border-radius: 14px;
  border-top: 2px solid var(--brand-aqua);
  background: linear-gradient(180deg, rgba(7,22,37,0.20) 0%, rgba(7,22,37,0.74) 62%);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 600ms var(--ease-out-quart), transform 600ms var(--ease-out-quart);
}
.ba-quote.is-active { opacity: 1; transform: translateY(0); }
.ba-quote__text {
  margin: 0 0 8px;
  font-size: clamp(0.98rem, 1.5vw, 1.18rem);
  line-height: 1.4;
  font-style: italic;
  text-wrap: balance;
}
.ba-quote__cite {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 0.82rem;
  color: rgba(255,255,255,0.9);
}
.ba-quote__name { font-weight: 800; font-style: normal; }
.ba-quote__src { display: inline-flex; align-items: center; gap: 5px; opacity: 0.88; }
.ba-quote__google { width: 13px; height: 13px; display: inline-flex; }
.ba-quote__google svg { width: 100%; height: 100%; }
/* Drag handle stays grabbable above the quote band */
.ba-slider--quotes .comparison__handle { z-index: 6; }

@media (prefers-reduced-motion: reduce) {
  .ba-quote { transition: none; transform: none; }
}
@media (max-width: 980px) {
  .ba-quote { padding: 12px 14px; }
  .ba-quote__text { font-size: 1rem; }
}

/* ── Trustindex review-card brand polish (light-DOM override) ─────────────────
   The widget renders in plain light DOM, so we can restyle its cards. This is
   intentionally a thin, targeted override (cards only — text colour left to the
   widget so it stays readable). BRITTLE: if Trustindex changes its markup these
   class names may move; the robust home for colour is the Trustindex dashboard.
   Default card is flat #f4f4f4; lift it to crisp white with a brand-aqua accent.
   The widget sets the grey via an (0,6,0) !important rule keyed to
   [data-layout-id][data-set-id][data-pid], so we must out-specify it: we match
   the stable data-pid (presence-match the volatile layout/set attrs) and add the
   .ti-reviews-container ancestor to reach (0,8,0). The AI "Review summary" card
   keeps its own gradient (excluded via :not). */
.ti-widget[data-layout-id][data-set-id][data-pid="be2d4d5711e25754411651b3457"] .ti-reviews-container .ti-review-item:not(.ti-ai-summary-item) .ti-inner {
  /* Pearl (the Presentation card's blue-white), lightened slightly for text legibility. */
  background: linear-gradient(135deg, rgba(255,255,255,0.99) 0%, rgba(236,250,253,0.97) 54%, rgba(214,244,249,0.94) 100%) !important;
  border-top: 3px solid var(--brand-aqua) !important;
  border-radius: 14px !important;
  /* Tighter shadow so it isn't clipped by the section/panel/carousel overflow:hidden. */
  box-shadow: 0 10px 22px rgba(7, 22, 37, 0.14) !important;
}
/* Give the cards room to cast their shadow inside the clipping carousel container. */
.ti-widget[data-pid="be2d4d5711e25754411651b3457"] .ti-reviews-container,
.ti-widget[data-pid="be2d4d5711e25754411651b3457"] .ti-reviews-container-wrapper {
  padding-bottom: 8px !important;
}

/* ── Hero floating before/after thumbnails ───────────────────────────────────
   Fills the hero's side space with proof (same before/after assets as the
   Testimonials section) without crowding the headline. Sit behind the content,
   low opacity, soft shadow. Desktop only — phone keeps the clean basic hero. */
.hero__photos { display: none; }
.hero--home .hero__content { position: relative; z-index: 1; }

@media (min-width: 981px) {
  .hero__photos {
    display: block;
    position: absolute;
    inset: 0;
    pointer-events: none;
  }
  .hero__photo {
    position: absolute;
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 18px 44px rgba(10, 41, 72, 0.18);
    opacity: 0.5;
  }
  .hero__photo img {
    display: block;
    width: 100%;
    height: 100%;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    filter: saturate(0.92);
  }
  .hero__photo--tl { top: 10%;    left: 8.5%;  width: clamp(174px, 14.5vw, 244px); }
  .hero__photo--bl { bottom: 9%;  left: 11%;   width: clamp(150px, 12vw, 210px); }
  .hero__photo--tr { top: 9%;     right: 9%;   width: clamp(150px, 12vw, 210px); }
  .hero__photo--br { bottom: 8%;  right: 11%;  width: clamp(174px, 14.5vw, 244px); }

  /* Trim the hero so the Testimonials section peeks at the bottom of the
     first screen — pulls content up and gives the empty space a purpose. */
  .hero--home {
    min-height: 64vh;
    padding-top: calc(var(--header-height) + 84px);
    padding-bottom: 40px;
  }

  /* The testimonials peek now does the scroll cue's job; hiding it also avoids
     a collision with the CTAs in the shortened hero. */
  .hero--home .hero__scroll-cue { display: none; }
}

/* Carousel side arrows — pinned to the far edges of the viewport, clear
   of the centred drag handle. Siblings of the slides (not inside any
   .comparison) so they never fight the drag range input. */
.ba-slider__arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 50%;
  background: rgba(10, 41, 72, 0.42);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  cursor: pointer;
  transition: background 200ms ease, border-color 200ms ease;
}
.ba-slider__arrow--prev { left: 8px; }
.ba-slider__arrow--next { right: 8px; }
.ba-slider__arrow:hover,
.ba-slider__arrow:focus-visible {
  background: rgba(10, 41, 72, 0.68);
  border-color: rgba(255, 255, 255, 0.5);
}
/* White chevron reusing the .comparison__chevron border-rotate look,
   kept self-contained so it ignores the comparison's hover transforms. */
.ba-slider__arrow-chevron {
  width: 8px;
  height: 8px;
  border-top: 2px solid var(--white, #fff);
  border-left: 2px solid var(--white, #fff);
}
.ba-slider__arrow-chevron--left { transform: rotate(-45deg); margin-left: 3px; }
.ba-slider__arrow-chevron--right { transform: rotate(135deg); margin-right: 3px; }


/* ── RESULTS page split hero ─────────────────────────────────────
   case-studies.html leads with a centred page H1, then a split below
   it: the rotating before/after .ba-slider (with its "Drag to compare"
   eyebrow above it) as the enlarged visual hero on the left, and the
   supporting copy (lead + bullets + CTA) on the right. */

/* Top breathing room so the H1 + slider clear the fixed header,
   matching the location-page hero (clamp(128,13vw,188)). */
.results-hero {
  padding-top: clamp(128px, 13vw, 188px);
  position: relative;
  overflow: hidden;
}

/* Centred page H1 sits full-width above the split with a clear gap
   below it before the slider/copy row begins. */
.results-hero__intro {
  margin-bottom: clamp(32px, 4vw, 56px);
}

/* Match the page H1 to the site editorial heading (h2.headline--editorial:
   Montserrat, weight 500), overriding the muted generic ".section-intro h1"
   so this single page H1 reads as a clean, on-brand headline. */
.results-hero__intro h1 {
  font-family: "Montserrat", "Poppins", Arial, Helvetica, sans-serif;
  font-size: clamp(2.4rem, 5.2vw, 3.6rem);
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.08;
  color: var(--ink);
  max-width: none;
}

/* Media column: the eyebrow stacks above the slider, both centred on
   the slider's own width. */
.results-hero__media {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.results-hero__media .eyebrow {
  color: var(--brand-aqua);
  text-align: center;
  margin: 0 0 14px;
}

/* Enlarge the slider so it clearly dominates as the hero. It keeps the
   portrait 4/5 comparison aspect-ratio but is allowed a much wider cap
   than the default 440px (which still applies anywhere else). */
.results-hero .split .ba-slider {
  max-width: 640px;
  margin: 0 auto;
}

/* The .hero__actions secondary button defaults to white-on-dark for
   the dark home hero. On this light paper background, give the phone
   button the readable light-background treatment used on location
   pages (matches .hero__actions.area-highlight__actions). */
.results-hero .hero__actions .button--secondary {
  background: linear-gradient(135deg, rgba(82, 243, 248, 0.34), rgba(47, 159, 214, 0.18));
  color: #114a73;
  border-color: rgba(35, 159, 214, 0.36);
  box-shadow: 0 12px 24px rgba(7, 22, 37, 0.07);
  text-shadow: none;
}

.results-hero .hero__actions .button--secondary:hover,
.results-hero .hero__actions .button--secondary:focus {
  background: linear-gradient(135deg, rgba(82, 243, 248, 0.48), rgba(47, 159, 214, 0.24));
  color: #071625;
  border-color: rgba(35, 159, 214, 0.5);
}

@media (min-width: 981px) {
  /* Give the enlarged slider the dominant column and the shorter copy
     the narrower one, and vertically centre the copy against the tall
     portrait slider so the block reads balanced. */
  .results-hero .split {
    grid-template-columns: minmax(0, 1.35fr) minmax(280px, 0.78fr);
    align-items: center;
  }
  /* One-line H1 on desktop (mirrors the .hero--home h1 nowrap pattern). */
  .results-hero__intro h1 {
    white-space: nowrap;
  }
}

/* Mobile: the split collapses to one column (DOM order puts the
   eyebrow + slider first, then the copy). Re-centre the slider and
   rein in its width so the portrait comparison doesn't tower on small
   screens. */
@media (max-width: 980px) {
  .results-hero .split .ba-slider {
    max-width: 440px;
    margin: 0 auto;
  }
  .results-hero .results-hero__copy {
    text-align: center;
    justify-items: center;
  }
  .results-hero .results-hero__copy .tick-list {
    text-align: left;
  }
  .results-hero .results-hero__copy .hero__actions {
    justify-content: center;
  }
}