/* ============================================================
   SOS Plumbing & Heating — design system
   Concept: "Send the Signal" — morse SOS structure,
   water (aqua) vs heat (copper) on deep indigo, porcelain relief.
   ============================================================ */

/* ---------- Fonts ---------- */
@font-face {
  font-family: 'Clash Display';
  src: url('../fonts/clash-display-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Clash Display';
  src: url('../fonts/clash-display-600.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Clash Display';
  src: url('../fonts/clash-display-700.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('../fonts/general-sans-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('../fonts/general-sans-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('../fonts/general-sans-600.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Spline Sans Mono';
  src: url('../fonts/spline-sans-mono-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Spline Sans Mono';
  src: url('../fonts/spline-sans-mono-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
  --abyss: #0a0714;
  --abyss-2: #110b20;
  --ink: #1d1235;
  --ink-2: #271a47;
  --brand: #704c98;
  --iris: #a184cc;
  --iris-deep: #3d2854;
  --gold: #f0d353;
  --gold-bright: #f7e27e;
  --aqua: #f0d353; /* retired — aliased to gold (rev 4) */
  --copper: #d08a54;
  --copper-bright: #e8a76c;
  --porcelain: #f4f2f7;
  --porcelain-2: #e9e5f0;
  --text: #ece9f4;
  --text-muted: #a49dbf;
  --text-dark: #1c142b;
  --text-dark-muted: #5c5378;
  --line: rgba(161, 132, 204, .18);
  --line-light: rgba(28, 20, 43, .12);

  --font-display: 'Clash Display', 'Avenir Next', sans-serif;
  --font-body: 'General Sans', -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'Spline Sans Mono', 'SF Mono', monospace;

  /* Trimmed from clamp(3rem, 9.5vw, 7.5rem): the headline is now a real
     sentence rather than a two-word brand line, so it needs to set smaller to
     stay readable and keep the CTAs above the fold. */
  --size-hero: clamp(2.6rem, 8vw, 6.4rem);
  --size-h2: clamp(2.1rem, 4.6vw, 3.6rem);
  --size-h3: clamp(1.35rem, 2.4vw, 1.8rem);
  --size-body: 1.0625rem;
  --size-small: .9rem;
  --size-mono: .8125rem;

  --container: 1240px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --section-pad: clamp(4.5rem, 10vw, 8.5rem);

  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
}

/* ---------- Reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font-body);
  font-size: var(--size-body);
  line-height: 1.65;
  color: var(--text);
  background: var(--abyss);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; background: none; border: 0; cursor: pointer; color: inherit; }
ul, ol { list-style: none; }
::selection { background: var(--iris-deep); color: #fff; }

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: absolute; left: -999px; top: 0; z-index: 200;
  background: var(--gold); color: #221a08;
  padding: .6rem 1rem; font-family: var(--font-mono); font-size: var(--size-mono);
}
.skip-link:focus { left: 0; }

.container { max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }

/* ---------- Morse signature ---------- */
.morse { display: inline-flex; align-items: center; gap: 7px; }
.morse i {
  display: block; height: 4px; border-radius: 999px;
  background: currentColor;
}
.morse .md { width: 4px; }
.morse .mD { width: 16px; }
.morse.is-live i { animation: morse-blink 3.6s infinite; }
/* SOS timing: dots(0,1,2) dashes(3,4,5) dots(6,7,8) */
.morse.is-live i:nth-child(1) { animation-delay: 0s; }
.morse.is-live i:nth-child(2) { animation-delay: .25s; }
.morse.is-live i:nth-child(3) { animation-delay: .5s; }
.morse.is-live i:nth-child(4) { animation-delay: .9s; }
.morse.is-live i:nth-child(5) { animation-delay: 1.35s; }
.morse.is-live i:nth-child(6) { animation-delay: 1.8s; }
.morse.is-live i:nth-child(7) { animation-delay: 2.3s; }
.morse.is-live i:nth-child(8) { animation-delay: 2.55s; }
.morse.is-live i:nth-child(9) { animation-delay: 2.8s; }
@keyframes morse-blink {
  0%, 12%, 100% { opacity: .35; }
  4%, 8% { opacity: 1; }
}

.eyebrow {
  display: inline-flex; align-items: center; gap: .9rem;
  font-family: var(--font-mono); font-size: var(--size-mono);
  font-weight: 500; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gold);
}
.eyebrow .morse { color: var(--gold); opacity: .85; }
.eyebrow--copper, .eyebrow--copper .morse { color: var(--copper-bright); }

/* ---------- Type ---------- */
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 600; line-height: 1.04; letter-spacing: -.01em; }
/* Display leading must live here, not only on h1-h4: the keyword-H1 pattern
   renders the big brand line as a <p class="hero__display">, so it never
   matched the heading rule and inherited body leading (1.65). Harmless on
   desktop where it sets one line, but it split the two mobile lines apart. */
.h-display { font-size: var(--size-hero); font-weight: 700; letter-spacing: -.02em; line-height: 1.02; }
.h-section { font-size: var(--size-h2); }
.h-card { font-size: var(--size-h3); font-weight: 600; }
.lede { font-size: clamp(1.1rem, 1.6vw, 1.3rem); line-height: 1.6; color: var(--text); max-width: 56ch; }
.on-light .lede { color: var(--text-dark-muted); }

.section-head { display: grid; gap: 1.1rem; margin-bottom: clamp(2.5rem, 5vw, 4rem); max-width: 780px; }
.section-head .h-section { text-wrap: balance; }

/* ---------- Buttons ---------- */
.btn {
  position: relative;
  display: inline-flex; align-items: center; gap: .7rem;
  padding: 1rem 1.6rem;
  font-family: var(--font-mono); font-size: var(--size-mono);
  font-weight: 500; letter-spacing: .1em; text-transform: uppercase;
  border-radius: 10px;
  transition: transform .35s var(--ease-out), background .35s, color .35s, box-shadow .35s;
  will-change: transform;
}
.btn svg { width: 15px; height: 15px; flex: none; transition: transform .35s var(--ease-out); }
.btn:hover svg { transform: translateX(4px); }
.btn:active { transform: scale(.97); }

.btn--signal {
  background: var(--gold); color: #221a08;
  box-shadow: 0 0 0 0 rgba(240, 211, 83, 0);
}
.btn--signal:hover { background: var(--gold-bright); box-shadow: 0 8px 40px -8px rgba(240, 211, 83, .55); transform: translateY(-2px); }

/* The secondary CTA ("Request service online") was a near-invisible hairline
   over a photo. It now takes the offer band's purple with a white border, so
   it reads as a real button next to the gold call CTA without competing with
   it for primacy. */
.btn--ghost {
  color: #fff;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .85);
  background: var(--iris-deep);
}
.btn--ghost:hover { box-shadow: inset 0 0 0 1px #fff; background: #4b3268; transform: translateY(-2px); }
.on-light .btn--ghost { color: var(--text-dark); box-shadow: inset 0 0 0 1px rgba(20,22,43,.25); background: transparent; }
.on-light .btn--ghost:hover { box-shadow: inset 0 0 0 1px var(--text-dark); background: rgba(20,22,43,.05); }

/* "Request service" buttons. These rules were written to beat the styles
   Housecall Pro's booking script injected; that script is gone, so the
   !important war is over, but the look they settled on is kept exactly. */
.btn.request-button {
  background: var(--iris-deep);
  color: #fff;
  border: 0;
  border-radius: 10px;
  line-height: inherit;
  padding: 1rem 1.6rem;
  display: inline-flex;
}
.btn--ghost.request-button { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .85); }
.btn--ghost.request-button:hover { box-shadow: inset 0 0 0 1px #fff; background: #4b3268; }
.btn--signal.request-button { background: var(--gold); color: #221a08; }
.btn--signal.request-button:hover { background: var(--gold-bright); box-shadow: 0 8px 40px -8px rgba(240, 211, 83, .55); }
/* Lands below the sticky nav when a button scrolls to the form, or when
   another page links to /contact/#request. */
#request { scroll-margin-top: 96px; }

/* ---------- Top bar + nav ---------- */
.topbar {
  position: relative; z-index: 60;
  background: linear-gradient(90deg, var(--ink) 0%, var(--iris-deep) 55%, var(--ink) 100%);
  font-family: var(--font-mono); font-size: .75rem; letter-spacing: .08em;
}
.topbar__in {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding-block: .5rem;
}
.topbar__note { display: flex; align-items: center; gap: .7rem; color: rgba(233, 234, 244, .85); text-transform: uppercase; }
.topbar__note .morse { color: var(--gold); }
.topbar a { color: #fff; font-weight: 500; white-space: nowrap; }
.topbar a:hover { color: var(--gold); }

.nav {
  position: sticky; top: 0; z-index: 50;
  background: rgba(7, 10, 24, .72);
  -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px);
  border-bottom: 1px solid rgba(161, 132, 204, .12);
  transition: background .4s, box-shadow .4s;
}
.nav.is-scrolled { background: rgba(7, 10, 24, .88); box-shadow: 0 14px 40px -18px rgba(0, 0, 0, .65); }
/* signal-strength scroll progress */
.nav::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: linear-gradient(90deg, var(--gold), var(--brand));
  transform-origin: left;
  transform: scaleX(var(--scroll-progress, 0));
  pointer-events: none;
}
.nav__in { display: flex; align-items: center; justify-content: space-between; gap: 2rem; height: 76px; }
.brand { display: flex; align-items: center; gap: .8rem; }
.brand__mark { width: auto; height: 46px; flex: none; }
.brand__text { display: grid; line-height: 1.1; }
.brand__name { font-family: var(--font-display); font-weight: 700; font-size: 1.45rem; letter-spacing: .02em; color: #fff; }
.brand__tag { font-family: var(--font-mono); font-size: .6rem; letter-spacing: .22em; text-transform: uppercase; color: var(--text-muted); }

.nav__links { display: flex; align-items: center; gap: 1.4rem; }
.nav__links > li > a, .nav__links > li > button { white-space: nowrap; }
.nav__links > li { position: relative; }
.nav__links a:not(.btn) {
  font-size: .95rem; font-weight: 500; color: var(--text);
  padding-block: .4rem;
  position: relative;
}
.nav__links > li > a:not(.btn)::after {
  content: ''; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 2px; border-radius: 2px;
  background: var(--gold);
  transform: scaleX(0); transform-origin: left;
  transition: transform .35s var(--ease-out);
}
.nav__links > li > a:not(.btn):hover::after,
.nav__links > li > a[aria-current="page"]::after { transform: scaleX(1); }

.nav__phone { display: inline-flex; align-items: center; gap: .55rem; padding: .7rem 1.15rem; }
.btn.nav__book.request-button { padding: .7rem 1.15rem; }
@media (max-width: 1280px) { .nav__links .nav__book.request-button { display: none; } }

/* dropdown */
.nav__drop { position: relative; }
.nav__drop > button {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .95rem; font-weight: 500; padding-block: .4rem;
}
.nav__drop > button svg { width: 10px; height: 10px; transition: transform .3s; }
.nav__drop.is-open > button svg { transform: rotate(180deg); }
.drop {
  position: absolute; top: calc(100% + 14px); left: 50%;
  translate: -50% 0;
  min-width: 280px;
  background: var(--ink);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: .6rem;
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, .6);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .3s, transform .3s, visibility .3s;
}
.nav__drop.is-open .drop,
.nav__drop:focus-within .drop { opacity: 1; visibility: visible; transform: translateY(0); }
.drop a {
  display: flex; align-items: center; gap: .7rem;
  padding: .65rem .8rem; border-radius: 9px;
  font-size: .92rem; color: var(--text);
}
.drop__item { position: relative; }
.drop__item > a .sub-arrow {
  margin-left: auto; width: 9px; height: 9px; opacity: .5; flex: none;
  transition: transform .25s, opacity .25s;
}
.drop__item:hover > a .sub-arrow, .drop__item:focus-within > a .sub-arrow { opacity: 1; transform: translateX(2px); color: var(--gold); }
.drop2 {
  position: absolute; left: calc(100% + 10px); top: -8px;
  min-width: 250px;
  background: var(--ink);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: .6rem;
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, .6);
  opacity: 0; visibility: hidden; transform: translateX(6px);
  transition: opacity .25s, transform .25s, visibility .25s;
}
.drop2::before {
  content: ''; position: absolute; left: -12px; top: 0; bottom: 0; width: 12px;
}
.drop__item:hover .drop2, .drop__item:focus-within .drop2 {
  opacity: 1; visibility: visible; transform: translateX(0);
}
.drop--areas {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 0 .4rem; min-width: 460px;
}
.drop--areas .drop__all { grid-column: 1 / -1; }
.drop a:hover { background: rgba(161, 132, 204, .1); color: var(--gold); }
.drop a .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--gold); opacity: .7; flex: none; }
.drop a .dot--heat { background: var(--copper); }

/* mobile */
.nav__burger { display: none; width: 44px; height: 44px; position: relative; z-index: 70; }
.nav__burger span {
  position: absolute; left: 10px; right: 10px; height: 2px; border-radius: 2px;
  background: var(--text); transition: transform .4s var(--ease-out), opacity .3s, top .4s var(--ease-out);
}
.nav__burger span:nth-child(1) { top: 15px; }
.nav__burger span:nth-child(2) { top: 21px; }
.nav__burger span:nth-child(3) { top: 27px; }
.nav__burger[aria-expanded="true"] span:nth-child(1) { top: 21px; transform: rotate(45deg); }
.nav__burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__burger[aria-expanded="true"] span:nth-child(3) { top: 21px; transform: rotate(-45deg); }

.mobile-menu {
  position: fixed; inset: 0; z-index: 60;
  background: linear-gradient(160deg, var(--abyss) 0%, var(--ink) 100%);
  display: grid; align-content: safe center; gap: .4rem;
  padding: calc(var(--gutter) + 3rem) var(--gutter) var(--gutter);
  overflow-y: auto;
  opacity: 0; visibility: hidden; transition: opacity .4s, visibility .4s;
}
.mobile-menu.is-open { opacity: 1; visibility: visible; }
.mobile-menu__close {
  position: absolute; top: 1rem; right: 1.1rem;
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center;
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--text);
}
.mobile-menu__close:hover { color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); }
.mobile-menu__close svg { width: 17px; height: 17px; }
/* Menu links only. The request button became a link when the HCP widget was
   retired; it keeps its button styling, exactly as before. */
.mobile-menu a:where(:not(.request-button)) {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.8rem, 7vw, 2.6rem);
  padding-block: .45rem;
  display: flex; align-items: baseline; gap: 1rem;
  transform: translateY(24px); opacity: 0;
  transition: transform .5s var(--ease-out), opacity .5s;
}
.mobile-menu.is-open a:where(:not(.request-button)) { transform: translateY(0); opacity: 1; }
.mobile-menu a small { font-family: var(--font-mono); font-size: .7rem; letter-spacing: .2em; color: var(--gold); text-transform: uppercase; }
.mobile-menu a:where(:not(.request-button)):hover { color: var(--gold); }
.mobile-menu__cta { margin-top: 1.6rem; display: flex; flex-wrap: wrap; gap: .8rem; }
.mobile-menu__cta .btn { opacity: 0; transition: opacity .5s .25s; }
.mobile-menu.is-open .btn { opacity: 1; }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: min(72vh, 760px);
  display: grid; align-items: end;
  overflow: clip;
  isolation: isolate;
}
.hero__gl, .hero__fallback {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%;
}
.hero__fallback {
  background:
    radial-gradient(120% 90% at 70% 0%, rgba(112, 76, 152, .5) 0%, transparent 55%),
    radial-gradient(100% 70% at 20% 100%, rgba(240, 211, 83, .10) 0%, transparent 50%),
    linear-gradient(180deg, var(--abyss-2), var(--abyss));
}
/* The crew photo replaces the WebGL water surface. Unlike the interior heroes,
   this composition puts its subject across the full width and the copy is
   bottom-anchored (.hero uses align-items: end), so the scrim is weighted to
   the bottom rather than the left. That keeps six faces visible and still
   gives the headline a solid ground to sit on. */
.hero__media {
  position: absolute; inset: 0; z-index: -2; overflow: hidden;
  pointer-events: none;
}
.hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: center 32%; }
.hero__veil {
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg, rgba(10,7,20,.78) 0%, rgba(10,7,20,.66) 30%, rgba(17,11,32,.80) 58%, rgba(10,7,20,.94) 82%, var(--abyss) 100%),
    linear-gradient(90deg, rgba(17,11,32,.50) 0%, rgba(17,11,32,.20) 45%, rgba(17,11,32,.12) 100%);
  pointer-events: none;
}
@media (max-width: 900px) {
  .hero__media img { object-position: 58% 30%; }
  .hero__veil {
    background: linear-gradient(180deg, rgba(10,7,20,.70) 0%, rgba(17,11,32,.80) 40%, rgba(10,7,20,.94) 72%, var(--abyss) 100%);
  }
}
.hero__in {
  /* .container's auto inline margins make a grid item size to fit-content
     rather than stretch, so the homepage hero sat ~170px narrower than the
     nav. width:100% lets max-width do the work again. */
  width: 100%;
  padding-block: clamp(2.25rem, 4.5vh, 3.5rem) clamp(2.5rem, 5vh, 4rem);
  display: grid; gap: 2.2rem;
}
.hero__kicker { display: flex; align-items: center; gap: 1rem; }
.hero__copy { display: grid; gap: 1.4rem; }
.hero__display { display: block; color: #fff; text-wrap: balance; }
/* Was an outline: transparent fill plus a 1.5px gold stroke. It read as a
   hairline on phones and over the hero photo, so it is a solid fill now. */
.hero__display em { font-style: normal; color: var(--gold); }
.hero__sub {
  display: block;
  font-family: var(--font-body); font-weight: 400;
  font-size: clamp(1.05rem, 1.8vw, 1.35rem); line-height: 1.55; letter-spacing: 0;
  color: var(--text); max-width: 52ch;
}
.hero__sub strong { color: var(--text); font-weight: 500; }
.hero__cta { display: flex; flex-wrap: wrap; gap: .9rem; align-items: start; }
.hero__cta .or { font-family: var(--font-mono); font-size: .75rem; color: var(--text-muted); letter-spacing: .12em; text-transform: uppercase; padding-inline: .3rem; }
.hero__meta {
  display: flex; flex-wrap: wrap; gap: 1.4rem 2.6rem;
  border-top: 1px solid var(--line);
  padding-top: 1.6rem;
  font-family: var(--font-mono); font-size: var(--size-mono); letter-spacing: .05em;
  color: var(--text-muted);
}
.hero__meta b { color: #fff; font-weight: 500; }
.hero__meta .stars { color: var(--gold); letter-spacing: .18em; }

/* ---------- Ticker (trust marquee) ---------- */
.ticker {
  border-block: 1px solid rgba(61, 40, 84, .35);
  background: var(--gold);
  overflow: hidden; position: relative;
  padding-block: 1.05rem;
}
.ticker__track {
  display: flex; gap: 3.2rem; width: max-content;
  animation: ticker-scroll 36s linear infinite;
}
.ticker:hover .ticker__track { animation-play-state: paused; }
.ticker span {
  display: inline-flex; align-items: center; gap: 3.2rem;
  font-family: var(--font-mono); font-size: var(--size-mono);
  letter-spacing: .14em; text-transform: uppercase; color: var(--iris-deep);
  white-space: nowrap;
}
.ticker b { color: #2a1a3e; font-weight: 600; }
.ticker .sep { color: var(--brand); opacity: .8; }
@keyframes ticker-scroll { to { transform: translateX(-50%); } }

/* ---------- Services ---------- */
.section { padding-block: var(--section-pad); position: relative; }
.section--light { background: var(--porcelain); color: var(--text-dark); }
.section--light h2, .section--light h3 { color: var(--text-dark); }

.services__grid {
  display: grid; gap: 1.4rem;
  grid-template-columns: repeat(3, 1fr);
}
.svc {
  position: relative; border-radius: 18px; overflow: hidden;
  aspect-ratio: 3 / 3.8;
  display: flex; align-items: flex-end;
  background: var(--ink);
  transform: translateZ(0);
}
.svc__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1.1s var(--ease-out), filter .6s;
  filter: saturate(.92);
}
.svc:hover .svc__img { transform: scale(1.055); filter: saturate(1.05); }
.svc::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(185deg, rgba(7,10,24,0) 30%, rgba(7,10,24,.38) 58%, rgba(7,10,24,.92) 100%);
  transition: background .5s;
}
.svc__body {
  position: relative; z-index: 2; padding: 1.6rem;
  display: grid; gap: .55rem; width: 100%;
}
.svc__label {
  display: inline-flex; align-items: center; gap: .6rem;
  font-family: var(--font-mono); font-size: .72rem; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
}
.svc--water .svc__label { color: var(--gold); }
.svc--heat .svc__label { color: var(--copper-bright); }
.svc__label i { width: 22px; height: 1px; background: currentColor; opacity: .6; transition: width .45s var(--ease-out); }
.svc:hover .svc__label i { width: 44px; }
.svc h3 { color: #fff; font-size: 1.55rem; }
.svc p { font-size: .93rem; color: rgba(233, 234, 244, .78); line-height: 1.5; max-width: 34ch; }
.svc__go {
  position: absolute; top: 1.15rem; right: 1.15rem; z-index: 2;
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(7, 10, 24, .55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 1px solid rgba(233, 234, 244, .18);
  transition: background .35s, transform .45s var(--ease-spring), border-color .35s;
}
.svc__go svg { width: 15px; height: 15px; color: #fff; transition: transform .35s var(--ease-out); }
.svc:hover .svc__go { background: var(--aqua); border-color: var(--aqua); }
.svc--heat:hover .svc__go { background: var(--copper); border-color: var(--copper); }
.svc:hover .svc__go svg { color: var(--abyss); transform: rotate(45deg); }

/* ---------- Emergency band ---------- */
.sos-band {
  position: relative; overflow: clip;
  background: linear-gradient(120deg, #221540 0%, #3d2854 55%, #4a2f35 100%);
}
.sos-band::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(80% 120% at 85% 50%, rgba(240, 211, 83, .2) 0%, transparent 60%);
}
.sos-band__in {
  position: relative;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 2rem;
  padding-block: clamp(3rem, 6vw, 4.5rem);
}
.sos-band h2 { font-size: clamp(1.7rem, 3.4vw, 2.6rem); max-width: 22ch; color: #fff; }
.sos-band h2 em { font-style: normal; color: var(--gold); }
.sos-band__phone {
  display: grid; gap: .5rem; justify-items: start;
}
.sos-band__phone .phone-big {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.9rem, 4.2vw, 3.2rem);
  color: #fff; letter-spacing: .01em;
  display: inline-flex; align-items: center; gap: 1rem;
}
.sos-band__phone .phone-big:hover { color: var(--gold); }
.sos-band__phone small {
  display: inline-flex; align-items: center; gap: .8rem;
  font-family: var(--font-mono); font-size: .78rem; color: rgba(233,234,244,.7); letter-spacing: .14em; text-transform: uppercase;
}
.sos-band__phone small .morse { color: var(--gold); }

/* ---------- Process (pipe) ---------- */
.process { position: relative; }
.process__wrap { position: relative; display: grid; gap: 0; }
.process__pipe {
  position: absolute; left: 26px; top: 0; bottom: 0;
  width: 4px; border-radius: 4px;
  background: rgba(161, 132, 204, .15);
  overflow: hidden;
}
.process__pipe i {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, var(--gold), var(--brand));
  transform-origin: top;
  transform: scaleY(var(--pipe-fill, 0));
}
.process__pipe .pipe-drop {
  position: absolute; left: 50%;
  top: calc(var(--pipe-fill, 0) * 100%);
  translate: -50% -50%;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 18px 3px rgba(240, 211, 83, .55);
}
.step {
  position: relative;
  display: grid; grid-template-columns: 56px 1fr; gap: 1.6rem;
  padding-block: clamp(1.6rem, 3.5vw, 2.6rem);
}
.step + .step { border-top: 1px dashed rgba(161, 132, 204, .14); }
.step__node {
  position: relative; z-index: 2;
  width: 56px; height: 56px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--ink);
  border: 1px solid var(--line);
  transition: border-color .4s, box-shadow .4s;
}
.step__node svg { width: 22px; height: 22px; color: var(--gold); }
.step.is-lit .step__node { border-color: var(--gold); box-shadow: 0 0 24px -6px rgba(240, 211, 83, .5); }
.step__body { display: grid; gap: .5rem; max-width: 60ch; }
.step__num { font-family: var(--font-mono); font-size: .72rem; letter-spacing: .2em; color: var(--iris); text-transform: uppercase; }
.step h3 { font-size: 1.45rem; color: #fff; }
.step p { color: var(--text); }

/* ---------- Map section ---------- */
.areas { background: var(--abyss-2); overflow: clip; }
.areas__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: center;
}
.rimap { position: relative; aspect-ratio: .88; max-height: 640px; margin-inline: auto; width: 100%; }
.rimap canvas { width: 100%; height: 100%; display: block; }
.rimap__tip {
  position: absolute; pointer-events: none;
  background: var(--ink); border: 1px solid var(--line);
  font-family: var(--font-mono); font-size: .75rem; letter-spacing: .1em;
  padding: .45rem .7rem; border-radius: 8px;
  transform: translate(-50%, -140%);
  opacity: 0; transition: opacity .25s;
  white-space: nowrap; color: var(--gold); text-transform: uppercase;
}
.rimap__tip.is-on { opacity: 1; }
.rimap__legend {
  position: absolute; left: 0; bottom: -.4rem;
  display: flex; gap: 1.4rem;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-muted);
}
.rimap__legend span { display: inline-flex; align-items: center; gap: .5rem; }
.rimap__legend i { width: 8px; height: 8px; border-radius: 50%; background: var(--gold); }
.rimap__legend .hq i { background: var(--copper); }
/* Two columns since the service area list reached 27 towns. In one column it
   ran to roughly twice the height of the map beside it, which left the section
   unbalanced and pushed everything below it a long way down the page. */
.areas__list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 1.6rem; }
.area-link {
  display: flex; align-items: baseline; justify-content: space-between; gap: .6rem;
  padding: .72rem .2rem;
  border-bottom: 1px solid rgba(161, 132, 204, .12);
  transition: padding .35s var(--ease-out), border-color .35s;
}
/* The "plumber + heating" label repeated 27 times is noise, and in a half-width
   cell it crowds the longer names. It stays for wide viewports where there is
   room, and is dropped rather than allowed to wrap or collide. */
@media (max-width: 1180px) { .area-link span { display: none; } }
.area-link:hover { padding-left: .8rem; border-color: var(--gold); }
.area-link b { font-family: var(--font-display); font-weight: 600; font-size: 1.12rem; color: #fff; white-space: nowrap; }
.area-link:hover b { color: var(--gold); }
.area-link span { font-family: var(--font-mono); font-size: .62rem; white-space: nowrap; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.areas__note { margin-top: 1.4rem; font-size: .92rem; color: var(--text); max-width: 46ch; }

/* ---------- Reviews ---------- */
.reviews { overflow: clip; }
.reviews__rail { display: grid; gap: 1.2rem; }
.reviews__row { display: flex; gap: 1.2rem; width: max-content; }
.reviews__row--a { animation: rail-a 60s linear infinite; }
.reviews__row--b { animation: rail-b 74s linear infinite; }
.reviews:hover .reviews__row { animation-play-state: paused; }
@keyframes rail-a { to { transform: translateX(-50%); } }
@keyframes rail-b { from { transform: translateX(-50%); } to { transform: translateX(0); } }
/* Gold cards against the dark page: the review rail is the one block that gets
   to shout. Everything inside flips to the dark-on-light token pair, including
   the stars, which would otherwise be gold on gold and disappear. */
.review {
  width: clamp(300px, 34vw, 420px); flex: none;
  background: var(--gold);
  border: 1px solid rgba(28, 20, 43, .16);
  border-radius: 16px;
  padding: 1.6rem;
  display: grid; gap: .9rem; align-content: start;
  box-shadow: 0 18px 40px -22px rgba(0, 0, 0, .75);
}
.review__stars { color: var(--text-dark); font-size: 1.12rem; letter-spacing: .16em; line-height: 1; }
.review p { font-size: .95rem; line-height: 1.6; color: var(--text-dark); }
.review footer { display: flex; align-items: center; gap: .7rem; font-family: var(--font-mono); font-size: .74rem; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dark-muted); }
.review footer i { width: 18px; height: 1px; background: var(--text-dark); opacity: .45; }
.reviews__cta { margin-top: 2.4rem; display: flex; flex-wrap: wrap; align-items: center; gap: 1.4rem; }
.gbadge { display: inline-flex; align-items: center; gap: .8rem; font-family: var(--font-mono); font-size: .8rem; color: var(--text-muted); letter-spacing: .05em; }
.gbadge b { color: #fff; font-size: 1.05rem; }

/* ---------- Heat spotlight ---------- */
.heat {
  position: relative; overflow: clip; isolation: isolate;
}
.heat__bg {
  position: absolute; inset: 0; z-index: -1;
  width: 100%; height: 100%; object-fit: cover;
  filter: brightness(.6) saturate(1.05);
}
.heat::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgba(7, 10, 24, .93) 0%, rgba(7, 10, 24, .55) 55%, rgba(7, 10, 24, .25) 100%);
}
.heat__in { display: grid; gap: 1.6rem; max-width: 620px; padding-block: clamp(5rem, 11vw, 9rem); }
.heat h2 { color: #fff; }
.heat p { color: rgba(233, 234, 244, .82); }
.heat__brands { display: flex; flex-wrap: wrap; gap: 1rem 2.2rem; margin-top: .6rem; font-family: var(--font-mono); font-size: .78rem; letter-spacing: .16em; text-transform: uppercase; color: var(--copper-bright); }
.heat__brands span { display: inline-flex; align-items: center; gap: .6rem; }
.heat__brands i { width: 6px; height: 6px; border-radius: 50%; background: var(--copper); }

/* ---------- FAQ ---------- */
.faq__list { max-width: 820px; display: grid; gap: 0; }
.faq-item { border-bottom: 1px solid var(--line-light); }
.section:not(.section--light) .faq-item { border-color: rgba(161, 132, 204, .14); }
.faq-item summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem;
  padding-block: 1.35rem;
  font-family: var(--font-display); font-weight: 600; font-size: 1.18rem;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary .faq-x {
  flex: none; position: relative; width: 14px; height: 14px; align-self: center;
}
.faq-item summary .faq-x::before, .faq-item summary .faq-x::after {
  content: ''; position: absolute; background: currentColor; border-radius: 2px;
  transition: transform .35s var(--ease-out);
}
.faq-item summary .faq-x::before { left: 0; right: 0; top: 6px; height: 2px; }
.faq-item summary .faq-x::after { top: 0; bottom: 0; left: 6px; width: 2px; }
.faq-item[open] summary .faq-x::after { transform: scaleY(0); }
.faq-item .faq-a { padding-bottom: 1.5rem; max-width: 62ch; color: var(--text-dark-muted); }
.section:not(.section--light) .faq-item .faq-a { color: var(--text); }
.faq-item summary:hover { color: var(--brand); }
.section:not(.section--light) .faq-item summary:hover { color: var(--aqua); }

/* ---------- Final CTA ---------- */
.final-cta { text-align: center; position: relative; overflow: clip; }
.final-cta .h-section { max-width: 20ch; margin-inline: auto; }
.final-cta__in { display: grid; gap: 1.8rem; justify-items: center; position: relative; }
.final-cta .morse { color: var(--gold); }
.final-cta__actions { display: flex; flex-wrap: wrap; gap: .9rem; justify-content: center; }
.final-cta__ring {
  position: absolute; left: 50%; top: 50%; z-index: -1;
  width: 900px; height: 900px; translate: -50% -50%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(112, 76, 152, .25) 0%, transparent 60%);
  pointer-events: none;
}

/* ---------- Footer ---------- */
.footer {
  border-top: 1px solid rgba(161, 132, 204, .14);
  background: var(--abyss-2);
  padding-block: clamp(3.5rem, 7vw, 5.5rem) 2rem;
  font-size: .95rem;
}
.footer__grid {
  display: grid; gap: 3rem;
  grid-template-columns: 1.4fr 1fr 1fr 1.2fr;
  margin-bottom: 3.5rem;
}
/* Screen-reader-only text utility. Not currently used by the headline, which
   labels its heading instead, but kept as the standard tool for the next time
   visible text and accessible text need to differ. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* Inline links inside body copy were distinguished by colour alone, which
   Lighthouse flags and which fails for low-vision and colour-blind readers. */
.lede a, .areas__note a, p a[style*="--gold"], .offer a { text-decoration: underline; text-underline-offset: .18em; text-decoration-thickness: 1px; }

.footer h2 { font-family: var(--font-mono); font-size: .72rem; font-weight: 500; letter-spacing: .2em; text-transform: uppercase; color: var(--iris); margin-bottom: 1.1rem; }
.footer ul { display: grid; gap: .55rem; }
.footer a:hover { color: var(--aqua); }
.footer__brand { display: grid; gap: 1rem; align-content: start; justify-items: start; }
.footer__brand p { color: var(--text); font-size: .92rem; max-width: 34ch; }
.footer__nap { display: grid; gap: .35rem; color: var(--text-muted); font-style: normal; }
.footer__nap a { color: var(--text); font-weight: 500; }
/* Hours moved into the sitewide NAP so every page carries name, address, phone
   and hours rather than only the 15 pages that spelled them out in body copy. */
.footer__hours { font-size: .82rem; line-height: 1.45; margin-top: .15rem; }
/* ---------- Footer partner block (Viessmann ViPRO) ---------- */
.footer__partners {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 1.6rem 2.4rem;
  padding: 1.8rem 0;
  border-top: 1px solid rgba(161, 132, 204, .12);
}
.footer__partners-copy { max-width: 46ch; display: grid; gap: .5rem; }
.footer__partners-copy h2 { margin-bottom: 0; }
.footer__partners-copy p { color: var(--text); font-size: .9rem; line-height: 1.55; }
.footer__partners-copy a { color: var(--gold); }
.partner-chip {
  display: grid; place-items: center; flex: none;
  background: #fff; border-radius: 14px;
  padding: .9rem 1.4rem;
  box-shadow: 0 10px 30px -14px rgba(0, 0, 0, .7);
  transition: transform .35s var(--ease-out), box-shadow .35s;
}
.partner-chip img { width: 172px; height: auto; }
.partner-chip:hover { transform: translateY(-3px); box-shadow: 0 18px 40px -16px rgba(240, 211, 83, .45); }
@media (max-width: 640px) {
  /* Two columns of towns is fine on a tablet; a phone needs one. */
  .areas__list { grid-template-columns: 1fr; } .footer__partners { justify-content: flex-start; } }

.footer__base {
  border-top: 1px solid rgba(161, 132, 204, .12);
  padding-top: 1.6rem;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem;
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .1em;
  color: var(--text-muted);
}
.footer__base .morse { color: var(--iris); }

/* ---------- Interior pages ---------- */
.page-hero {
  position: relative; overflow: clip;
  /* Top padding trimmed (was clamp(5rem,10vw,8rem), up to 128px) so the phone
     number and CTA row clear the fold on a laptop. */
  padding-block: clamp(3rem, 6vw, 4.75rem) clamp(3rem, 6vw, 5rem);
  background:
    radial-gradient(90% 100% at 85% 0%, rgba(112, 76, 152, .38) 0%, transparent 55%),
    radial-gradient(60% 80% at 10% 100%, rgba(240, 211, 83, .06) 0%, transparent 55%),
    var(--abyss-2);
}
.page-hero--heat {
  background:
    radial-gradient(90% 100% at 85% 0%, rgba(208, 138, 84, .28) 0%, transparent 55%),
    radial-gradient(60% 80% at 10% 100%, rgba(112, 76, 152, .28) 0%, transparent 55%),
    var(--abyss-2);
}
/* Hero spans the full container, matching the nav's logo-to-button width.
   The headline then sets on one line instead of two, which lifts the phone
   number and CTAs above the fold. Prose stays readable because .hero__sub
   and .lede keep their own ch-based caps. */
.page-hero__in { display: grid; gap: 1.05rem; position: relative; z-index: 1; }
/* 56ch pushed the longest ledes to three lines and dropped one page's CTAs
   below the fold. 62ch stays inside the 65-75 character comfort range and
   holds every hero to two. */
.page-hero__in .lede { max-width: 62ch; }

/* ---------- Location hero photography ----------
   The photo sits behind the copy and bleeds off the right edge. Two scrims do
   the work: a horizontal one so the left column stays readable over whatever
   the photo is doing, and a vertical one to seat the hero into the offer band
   below. Contrast is verified against the darkest scrim value, not the photo. */
.page-hero--photo { background: var(--abyss-2); }
.page-hero__media {
  position: absolute; inset: 0; z-index: 0; overflow: hidden;
  pointer-events: none;
}
.page-hero__media img {
  width: 100%; height: 100%; object-fit: cover; object-position: 72% center;
}
.page-hero__media::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(90deg, var(--abyss-2) 0%, rgba(17,11,32,.95) 34%, rgba(17,11,32,.86) 55%, rgba(17,11,32,.70) 78%, rgba(17,11,32,.34) 100%),
    linear-gradient(180deg, rgba(10,7,20,.55) 0%, rgba(10,7,20,0) 30%, rgba(10,7,20,.35) 78%, var(--abyss-2) 100%);
}
@media (max-width: 900px) {
  /* On a narrow screen the copy spans the full width, so the photo becomes a
     texture behind it rather than a subject beside it. */
  .page-hero__media img { object-position: 68% center; }
  .page-hero__media::after {
    background:
      linear-gradient(180deg, rgba(10,7,20,.86) 0%, rgba(17,11,32,.92) 45%, var(--abyss-2) 100%);
  }
}
.page-hero__in > * {
  opacity: 0; transform: translateY(22px);
  animation: ph-in .85s var(--ease-out) forwards;
}
.page-hero__in > *:nth-child(2) { animation-delay: .09s; }
.page-hero__in > *:nth-child(3) { animation-delay: .18s; }
.page-hero__in > *:nth-child(4) { animation-delay: .27s; }
.page-hero__in > *:nth-child(5) { animation-delay: .36s; }
@keyframes ph-in { to { opacity: 1; transform: none; } }
.page-hero h1 { font-size: clamp(2.4rem, 6vw, 4.4rem); color: #fff; text-wrap: balance; }
/* Keyword-H1 pattern (spec §11): the brand line is the visual headline
   (.hero__display); the <h1> carries the keyword at kicker scale beneath it.
   Google reads the tag, not the font size — nothing shrinks visually. */
.page-hero .hero__display {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(2.4rem, 6vw, 4.4rem);
  line-height: 1.04; letter-spacing: -.01em;
  color: #fff; text-wrap: balance;
}
.page-hero h1.hero__h1, .hero h1.hero__h1 {
  font-family: var(--font-mono); font-weight: 500;
  font-size: clamp(.85rem, 1.2vw, .95rem);
  letter-spacing: .18em; text-transform: uppercase;
  line-height: 1.5; color: var(--iris); text-wrap: balance;
}
.page-hero__in > *:nth-child(6) { animation-delay: .40s; }
.page-hero__in > *:nth-child(7) { animation-delay: .48s; }
.page-hero__in > *:nth-child(8) { animation-delay: .56s; }
.page-hero__in > *:nth-child(9) { animation-delay: .62s; }

/* ---------- proof-bar (spec §2.1) ---------- */
/* Google "G" inside the proof bar: the rating is Google's, so it should say so
   visually rather than only in words. Sized to the cap height of the line. */
.proof-g { display: inline-flex; align-items: center; gap: .42rem; }
.proof-g svg { width: .95em; height: .95em; flex: none; display: block; }
.proof-bar {
  display: flex; flex-wrap: wrap; gap: .35rem .7rem; align-items: center;
  font-family: var(--font-mono); font-size: .74rem; letter-spacing: .08em;
  /* Near-white rather than the muted lavender: this line now sits over hero
     photography, and on the night-shot service heroes the muted tone failed
     AA against porch light and headlights. Whitening the text fixes it without
     darkening the photograph, which the alternative (a heavier scrim) would. */
  text-transform: uppercase; color: var(--text);
}
.proof-bar b { color: var(--gold); font-weight: 500; }
.proof-bar .sep { color: var(--iris-deep); }

/* ---------- hero phone (spec §3.1) ---------- */
.hero-phone-wrap { display: grid; gap: .4rem; justify-items: start; margin-top: .3rem; }
.hero-phone {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.9rem, 4.4vw, 3.1rem);
  color: #fff; letter-spacing: .01em;
  display: inline-flex; align-items: center; gap: .8rem;
}
.hero-phone svg { width: .62em; height: .62em; color: var(--gold); flex: none; }
.hero-phone:hover { color: var(--gold); }
.hero-phone__sub {
  display: inline-flex; align-items: center; gap: .8rem;
  font-family: var(--font-mono); font-size: .74rem;
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted);
}
.hero-phone__sub .morse { color: var(--gold); }

/* ---------- offer-band (spec §2.2) ---------- */
.offer-band {
  background: linear-gradient(90deg, var(--ink) 0%, var(--iris-deep) 55%, var(--ink) 100%);
  border-block: 1px solid var(--line);
}
.offer-band__in { display: grid; grid-template-columns: repeat(3, 1fr); }
.offer {
  display: grid; gap: .3rem; align-content: start; text-align: left;
  padding: 1.15rem 1.5rem;
  border-left: 1px solid var(--line);
  transition: background .3s;
}
.offer-band__in .offer:first-child { border-left: 0; }
.offer b { font-family: var(--font-display); font-weight: 600; font-size: 1.02rem; color: #fff; line-height: 1.25; }
.offer > span { font-family: var(--font-mono); font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; color: var(--gold); }
.offer:hover { background: rgba(240, 211, 83, .07); }
/* The HCP-button overrides that used to live here are gone with the tile:
   every offer cell is a plain link now, so there is no injected style to fight. */
@media (max-width: 900px) {
  .offer-band__in { grid-template-columns: 1fr; }
  .offer { border-left: 0; border-top: 1px solid var(--line); }
  .offer-band__in .offer:first-child { border-top: 0; }
}

/* ---------- trust-strip (spec §2.3) ---------- */
.trust-strip {
  border-top: 1px solid rgba(161, 132, 204, .14);
  background: var(--abyss-2);
  padding-block: 1.25rem;
}
.trust-strip__in { display: flex; flex-wrap: wrap; gap: .7rem 1.9rem; align-items: center; justify-content: center; }
.tbadge {
  display: inline-flex; align-items: center; gap: .55rem;
  font-family: var(--font-mono); font-size: .68rem;
  letter-spacing: .15em; text-transform: uppercase;
  color: var(--text-muted); opacity: .85;
  transition: color .3s, opacity .3s;
}
.tbadge::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--gold); opacity: .55; }
.tbadge:hover { color: var(--gold); opacity: 1; }
/* The BBB badge is the one badge in the row that links out. It keeps the row's
   look rather than reading as body-copy link, with a faint underline so it is
   discoverable as a link and not colour alone. */
.tbadge--link { text-decoration: none; border-bottom: 1px solid rgba(240, 200, 96, .35); padding-bottom: 1px; }
.tbadge--link:hover { border-bottom-color: var(--gold); }
.form__captcha-wait { margin-top: .6rem; font-size: .86rem; color: var(--text-muted); }
.form__captcha-wait a { color: var(--gold); text-decoration: underline; }
.cf-turnstile { margin-top: .2rem; }

.tbadge--link:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 2px; }

/* ---------- pricing-policy (spec §2.5) ---------- */
.pricing-policy {
  margin-top: 2.4rem; padding: 1.3rem 1.6rem;
  border-left: 3px solid var(--gold);
  background: rgba(240, 211, 83, .05);
  border-radius: 0 14px 14px 0;
  display: grid; gap: .65rem; max-width: 66ch;
}
.pricing-policy h3 { font-size: 1.08rem; }
.pricing-policy ul { display: grid; gap: .45rem; }
.pricing-policy li { position: relative; padding-left: 1.5rem; color: var(--text); font-size: .96rem; }
.pricing-policy li::before {
  content: ''; position: absolute; left: 0; top: .62em;
  width: 8px; height: 4px; border-radius: 4px; background: var(--gold);
}
.financing-note { font-size: .88rem; color: var(--text-muted); }
.financing-note a { color: var(--gold); }

/* ---------- Coupons ---------- */
.coupon-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr)); gap: 1.6rem; }
.coupon {
  display: grid; grid-template-columns: 150px 1fr;
  border: 2px dashed var(--gold); border-radius: 18px;
  background: linear-gradient(180deg, rgba(240,211,83,.07), rgba(240,211,83,.02));
  overflow: hidden;
}
.coupon__stub {
  display: grid; align-content: center; justify-items: center; gap: .5rem;
  padding: 1.6rem 1rem; text-align: center;
  background: rgba(240, 211, 83, .12);
  border-right: 2px dashed var(--gold);
}
.coupon__amount { font-family: var(--font-display); font-weight: 700; font-size: 2.1rem; color: var(--gold); line-height: 1; }
.coupon__tag { font-family: var(--font-mono); font-size: .64rem; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.coupon__body { padding: 1.7rem; display: grid; gap: .8rem; align-content: start; }
.coupon__title { font-size: 1.4rem; color: #fff; }
.coupon__body p { color: var(--text); font-size: .95rem; }
.coupon__expiry { font-family: var(--font-mono); font-size: .74rem; letter-spacing: .1em; text-transform: uppercase; }
.coupon__expiry strong { color: var(--gold); }
.coupon__actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: .2rem; }
.coupon__terms { font-size: .78rem; color: var(--text-muted); opacity: .8; line-height: 1.5; }
@media (max-width: 560px) {
  .coupon { grid-template-columns: 1fr; }
  .coupon__stub { border-right: 0; border-bottom: 2px dashed var(--gold); padding: 1.1rem; }
}
@media print {
  .topbar, .nav, .mobile-menu, .callfab, .offer-band, .trust-strip,
  .footer, .final-cta, .lead-grid, .proof-bar, .hero-phone-wrap { display: none !important; }
  body { background: #fff; color: #000; }
  .coupon { border-color: #000; break-inside: avoid; }
  .coupon__amount, .coupon__expiry strong { color: #000; }
  .coupon__title, .coupon__body p, .coupon__terms { color: #000; }
  .coupon__stub { background: #f2f2f2; border-color: #000; }
  .coupon__actions { display: none; }
}

/* ---------- Real-work photo gallery ---------- */
.work-gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.2rem; }
.wg__item {
  border-radius: 16px; overflow: hidden;
  border: 1px solid var(--line); background: var(--ink);
  transition: transform .35s var(--ease-out), border-color .35s;
}
.wg__item:hover { transform: translateY(-4px); border-color: var(--gold); }
.wg__item img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.wg__item figcaption {
  padding: .85rem 1.1rem;
  font-family: var(--font-mono); font-size: .72rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted);
}
.on-light .wg__item { background: #fff; border-color: var(--line-light); }
.on-light .wg__item figcaption { color: var(--text-dark-muted); }
@media (max-width: 900px) { .work-gallery { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .work-gallery { grid-template-columns: 1fr; } }

/* ---------- Comparison table (in prose) ---------- */
.prose .cmp-wrap { overflow-x: auto; margin: 1.4rem 0; border: 1px solid var(--line); border-radius: 12px; }
.prose table.cmp { width: 100%; border-collapse: collapse; font-size: .95rem; min-width: 540px; }
.prose table.cmp th, .prose table.cmp td { text-align: left; padding: .8rem 1.05rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.prose table.cmp thead th { font-family: var(--font-mono); font-size: .7rem; letter-spacing: .12em; text-transform: uppercase; color: var(--gold); background: rgba(240, 211, 83, .05); }
.prose table.cmp tbody th { color: var(--text); font-weight: 600; font-family: var(--font-body); white-space: nowrap; }
.prose table.cmp td { color: var(--text); }
.prose table.cmp tbody tr:last-child th, .prose table.cmp tbody tr:last-child td { border-bottom: 0; }

/* ---------- Contrast "vs" block (why-sos) ---------- */
.vs-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem; }
.vs-card { border: 1px solid var(--line-light); border-radius: 16px; padding: 1.7rem; background: #fff; }
.on-light .vs-card { box-shadow: 0 24px 60px -34px rgba(20, 22, 43, .22); }
.vs-card h3 { font-size: 1.25rem; margin-bottom: 1.1rem; color: var(--text-dark); }
.vs-card ul { display: grid; gap: .7rem; }
.vs-card li { position: relative; padding-left: 1.9rem; color: var(--text-dark-muted); line-height: 1.5; }
.vs-card li::before { position: absolute; left: 0; top: -.05em; font-weight: 700; }
.vs-card--them li::before { content: '\2715'; color: #b3402f; }
.vs-card--us { border-color: var(--brand); background: linear-gradient(180deg, rgba(112,76,152,.05), #fff); }
.vs-card--us li::before { content: '\2713'; color: var(--brand); }
@media (max-width: 640px) { .vs-grid { grid-template-columns: 1fr; } }

/* ---------- Safety banner (gas lines) ---------- */
.safety-banner {
  display: flex; gap: .9rem; align-items: flex-start;
  margin-top: 1.4rem; padding: 1rem 1.3rem;
  border: 1px solid var(--copper); border-left-width: 3px;
  border-radius: 12px; background: rgba(208, 138, 84, .1);
  max-width: 60ch;
}
.safety-banner__icon { color: var(--copper-bright); font-size: 1.2rem; line-height: 1.4; flex: none; }
.safety-banner p { color: var(--text); font-size: .95rem; line-height: 1.5; }

/* ---------- SAP NAP block ---------- */
.sap-nap {
  display: inline-grid; gap: .2rem; margin-top: 1.2rem;
  padding: 1rem 1.4rem; border: 1px solid var(--line);
  border-radius: 12px; font-size: .92rem; justify-self: start;
}

/* ---------- inline lead form (spec §2.4) ---------- */
.lead-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(2.5rem, 6vw, 5rem); align-items: start;
}
@media (max-width: 900px) { .lead-grid { grid-template-columns: 1fr; } }
.form__fallback {
  display: none;
  padding: 1.4rem; border-radius: 12px;
  border: 1px solid var(--copper);
  background: rgba(208, 138, 84, .08);
  color: var(--text);
}
.form.is-failed .form__fallback { display: block; }
.form.is-failed .form__hideonsent { display: none; }
.crumbs {
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
  font-family: var(--font-mono); font-size: .74rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-muted);
}
.crumbs a:hover { color: var(--aqua); }
.crumbs .sep { color: var(--iris); }
.page-hero__cta { display: flex; flex-wrap: wrap; gap: .9rem; margin-top: .15rem; align-items: start; }
/* Each CTA carries a byline saying what happens after the press: one gets a
   person now, the other is asynchronous. Stack them so the note belongs to its
   button rather than floating under the pair. */
.cta-opt { display: grid; gap: .4rem; justify-items: start; }
.cta-opt__note { font-size: .82rem; line-height: 1.35; color: var(--text-muted); padding-inline: .15rem; }
@media (max-width: 560px) {
  .page-hero__cta, .hero__cta { flex-direction: column; align-items: stretch; }
  .cta-opt { width: 100%; justify-items: stretch; }
  .cta-opt .btn { justify-content: center; }
  .cta-opt__note { text-align: center; }
}

.split { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: clamp(2.5rem, 6vw, 5rem); align-items: start; }
.prose { display: grid; gap: 1.15rem; max-width: 66ch; }
.prose h2 { font-size: clamp(1.6rem, 3vw, 2.2rem); margin-top: 1.2rem; }
.prose h3 { font-size: 1.25rem; margin-top: .8rem; }
.prose p, .prose li { color: var(--text); }
.section--light .prose p, .section--light .prose li { color: var(--text-dark-muted); }
.prose ul { display: grid; gap: .6rem; }
.prose ul li { position: relative; padding-left: 1.6rem; }
.prose ul li::before {
  content: ''; position: absolute; left: 0; top: .62em;
  width: 8px; height: 4px; border-radius: 4px; background: var(--gold);
}
.prose--heat ul li::before { background: var(--copper); }
.prose strong { color: inherit; font-weight: 600; }
.section--light .prose strong { color: var(--text-dark); }

.sidecard {
  position: sticky; top: 106px;
  display: grid; gap: 1.1rem;
  background: var(--ink);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 1.8rem;
}
.section--light .sidecard { background: #fff; border-color: var(--line-light); box-shadow: 0 24px 60px -30px rgba(20, 22, 43, .25); }
.sidecard h3 { font-size: 1.3rem; }
.sidecard p { font-size: .93rem; color: var(--text); }
.section--light .sidecard p { color: var(--text-dark-muted); }
.sidecard .phone-line {
  font-family: var(--font-display); font-weight: 700; font-size: 1.7rem;
  color: var(--gold);
}
.section--light .sidecard .phone-line { color: var(--brand); }
.sidecard ul { display: grid; gap: .5rem; font-size: .88rem; color: var(--text-muted); }
.section--light .sidecard ul { color: var(--text-dark-muted); }
.sidecard ul li { display: flex; gap: .6rem; align-items: baseline; }
.sidecard ul li::before { content: '···'; color: var(--gold); letter-spacing: .1em; font-family: var(--font-mono); }

.svc-figure { border-radius: 18px; overflow: hidden; position: relative; }
.svc-figure img { width: 100%; height: 100%; object-fit: cover; }

.related { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.2rem; }
.related a {
  display: grid; gap: .5rem;
  padding: 1.4rem; border-radius: 14px;
  background: var(--ink); border: 1px solid var(--line);
  transition: transform .35s var(--ease-out), border-color .35s;
}
.related a:hover { transform: translateY(-4px); border-color: var(--gold); }
.related b { font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; color: #fff; }
.related span { font-family: var(--font-mono); font-size: .72rem; letter-spacing: .16em; text-transform: uppercase; color: var(--gold); }

/* area cards on hub */
.area-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.2rem; }
.area-card {
  display: grid; gap: .6rem; align-content: start;
  background: var(--ink); border: 1px solid var(--line); border-radius: 16px;
  padding: 1.6rem;
  transition: transform .35s var(--ease-out), border-color .35s;
}
.area-card:hover { transform: translateY(-4px); border-color: var(--gold); }
.area-card b { font-family: var(--font-display); font-size: 1.35rem; font-weight: 600; color: #fff; }
.area-card p { font-size: .9rem; color: var(--text-muted); }
.area-card span { font-family: var(--font-mono); font-size: .72rem; letter-spacing: .16em; text-transform: uppercase; color: var(--gold); margin-top: .4rem; }

/* contact form */
.form { display: grid; gap: 1.1rem; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
.field { display: grid; gap: .45rem; }
.field label { font-family: var(--font-mono); font-size: .72rem; letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted); }
/* Dark-form rule (spec decision 2): fields sit at a LIGHTER surface than
   their container, with a visible 1px border at rest — never border-on-focus
   only. Labels always above the field, placeholders at --text-muted minimum. */
.field input, .field select, .field textarea {
  font: inherit; color: var(--text);
  background: var(--ink-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: .85rem 1rem;
  transition: border-color .3s, background .3s;
}
.field ::placeholder { color: var(--text-muted); opacity: 1; }
/* Keep the gold ring. An earlier `outline: none` here outranked the global
   :focus-visible rule (0-2-1 vs 0-1-0), so keyboard users got no focus
   indicator on the lead form at all. Mouse focus still gets the quieter
   border+tint treatment; only keyboard focus draws the ring. */
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--gold); background: rgba(240, 211, 83, .05);
}
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}
.field__opt { font-weight: 400; opacity: .6; font-size: .85em; }
.field select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23f0d353' stroke-width='1.5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 1rem center; }
.form__note { font-size: .82rem; color: var(--text-muted); }
.form__success {
  display: none;
  padding: 1.4rem; border-radius: 12px;
  border: 1px solid var(--gold);
  background: rgba(240, 211, 83, .07);
  color: var(--text);
}
.form.is-sent .form__success { display: block; }
.form.is-sent .form__hideonsent { display: none; }

/* ---------- Request service popup ----------
   Full screen on a phone, a centred panel on a desktop. The emergency number
   sits in its own bar at the top so it is the first thing anyone in trouble
   sees; the gold submit stays the one primary action on the panel. */
html.rq-open { overflow: hidden; }
.rq {
  padding: 0; border: 0; margin: auto;
  width: min(560px, calc(100vw - 2rem));
  max-height: min(92dvh, 940px);
  background: var(--abyss-2); color: var(--text);
  border-radius: 18px;
  box-shadow: 0 40px 120px -20px rgba(0, 0, 0, .85), inset 0 0 0 1px var(--line);
  overflow: hidden;
}
.rq[open] { display: flex; flex-direction: column; }
.rq::backdrop { background: rgba(5, 3, 12, .74); backdrop-filter: blur(3px); }
.rq__form { display: flex; flex-direction: column; flex: 1; min-height: 0; gap: 0; }
.rq__head { flex: none; display: flex; align-items: stretch; background: var(--ink); border-bottom: 1px solid var(--line); }
.rq__emergency { flex: 1; display: grid; gap: .2rem; padding: 1rem 1.5rem; color: var(--text); text-decoration: none; }
.rq__em-kicker { font-family: var(--font-mono); font-size: .72rem; letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted); }
.rq__em-call { display: inline-flex; align-items: center; gap: .6rem; font-family: var(--font-display); font-weight: 600; font-size: 1.5rem; line-height: 1.1; color: var(--gold); }
.rq__em-call svg { width: 19px; height: 19px; flex: none; }
.rq__emergency:hover .rq__em-call { color: var(--gold-bright); }
.rq__em-note { font-size: .85rem; color: var(--text-muted); }
.rq__close { flex: none; width: 58px; display: grid; place-items: center; color: var(--text); border-left: 1px solid var(--line); background: transparent; }
.rq__close svg { width: 18px; height: 18px; }
.rq__close:hover { background: rgba(255, 255, 255, .05); color: var(--gold); }
.rq__body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 1.5rem 1.6rem 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.05rem; align-content: start; }
.rq__title { font-family: var(--font-display); font-weight: 600; font-size: 1.75rem; line-height: 1.1; margin: 0 0 .35rem; }
.rq__title:focus { outline: none; }
.rq__sub { color: var(--text-muted); font-size: .95rem; margin: 0; }
/* 16px is the size below which iPhones zoom the whole page on focus. Inputs
   default to a ~20-character intrinsic width; without width/min-width they
   refuse to shrink and two side by side overflow a phone screen. */
.rq .field input, .rq .field select, .rq .field textarea { font-size: 16px; width: 100%; min-width: 0; }
.rq .form__row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
/* The submit stays in view while the fields scroll under it, so nobody has
   to hunt for the button on a phone. */
.rq__actions {
  position: sticky; bottom: 0; z-index: 1;
  margin: 0 -1.6rem; padding: 1.1rem 1.6rem 1.4rem;
  background: linear-gradient(to bottom, rgba(17, 11, 32, 0), var(--abyss-2) 22%);
}
/* Service as tap targets (popup, non-service pages). The radio is visually
   hidden but stays focusable; the box beside it carries the look. */
.field[hidden], .rq__tiles[hidden], .rq__em-hint[hidden] { display: none; }
.rq__tiles { border: 0; padding: 0; margin: 0; min-width: 0; }
.rq__tiles legend { padding: 0; margin-bottom: .55rem; font-family: var(--font-mono); font-size: .72rem; letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted); }
.rq__tile-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .6rem; }
.rq-tile { position: relative; display: block; cursor: pointer; }
.rq-tile__input { position: absolute; opacity: 0; inset: 0; margin: 0; pointer-events: none; }
.rq-tile__box {
  display: flex; align-items: center; min-height: 3.4rem; height: 100%;
  padding: .75rem .95rem; border-radius: 12px;
  background: var(--ink-2); border: 1px solid var(--line);
  font-size: .95rem; line-height: 1.25; color: var(--text);
  transition: border-color .2s, background .2s;
}
.rq-tile:hover .rq-tile__box { border-color: var(--iris); }
.rq-tile__input:checked + .rq-tile__box { border-color: var(--gold); background: rgba(240, 211, 83, .1); box-shadow: inset 0 0 0 1px var(--gold); }
.rq-tile__input:focus-visible + .rq-tile__box { outline: 2px solid var(--gold); outline-offset: 3px; }
/* The last option sits alone on the final row; let it span the width. */
.rq__tile-grid .rq-tile:last-child:nth-child(odd) { grid-column: 1 / -1; }
.rq__em-hint { margin: -.2rem 0 0; padding: .75rem 1rem; border-radius: 10px; border: 1px solid var(--copper); background: rgba(208, 138, 84, .1); font-size: .9rem; color: var(--text); }
.rq__em-hint a { color: var(--gold); font-weight: 600; white-space: nowrap; }
.rq__submit { width: 100%; justify-content: center; padding-block: 1.15rem; font-size: .9rem; }
.rq__trust { margin: .85rem 0 0; text-align: center; font-size: .8rem; color: var(--text-muted); }
@media (max-width: 640px) {
  .rq { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0; margin: 0; }
  /* Phone and email side by side even on a phone, as specified. */
  .rq .form__row { gap: .75rem; }
  .rq__emergency { padding: .9rem 1.1rem; }
  .rq__em-call { font-size: 1.35rem; }
  .rq__body { padding: 1.25rem 1.1rem 0; gap: .95rem; }
  .rq__actions { margin: 0 -1.1rem; padding: .9rem 1.1rem calc(1rem + env(safe-area-inset-bottom)); }
  .rq__title { font-size: 1.5rem; }
}

/* ---------- Mobile sticky call button ---------- */
.callfab {
  position: fixed; left: 1rem; right: 1rem; bottom: 1rem; z-index: 55;
  display: none; gap: .6rem;
  opacity: 0; translate: 0 18px; pointer-events: none;
  transition: opacity .4s var(--ease-out), translate .4s var(--ease-out);
}
.callfab .btn {
  flex: 1; justify-content: center; padding-inline: 1rem;
  box-shadow: 0 18px 44px -12px rgba(240, 211, 83, .5), 0 4px 16px rgba(0, 0, 0, .4);
}
/* spec §2.8: the call button is visually dominant, not equal weight */
.callfab .callfab__call { flex: 1.9; font-size: .9rem; }
.callfab .btn.request-button {
  flex: 1;
  padding-inline: 1.6rem;
  background: var(--ink-2);
  box-shadow: inset 0 0 0 1px var(--iris), 0 4px 16px rgba(0, 0, 0, .4);
}
.request-button:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}
.callfab.is-on { opacity: 1; translate: 0 0; pointer-events: auto; }
@media (max-width: 900px) {
  html.js .callfab { display: flex; }
  /* The bar is fixed, so the last rows of the footer sat underneath it and
     could not be tapped. Reserve its height (56px) plus its 1rem inset. */
  html.js body { padding-bottom: calc(56px + 2rem); }

  /* Housecall Pro's chat loader appends #proChatIframeContainer with inline
     styles: bottom:0, right:0, width:110px, z-index:1200. That lands it right
     on top of the sticky call bar, covering the Request button. Lift it clear
     on mobile. !important is required because the widget writes the inline
     style attribute on load, on resize, and on every open/close.

     The [style*="width:110px"] test matches the collapsed bubble only. When
     the chat opens, the widget rewrites width to 100% (or 400px) and takes
     height:100vh, so this rule stops applying and the panel fills the screen
     as intended rather than being pushed up and clipped. */
  #proChatIframeContainer[style*="width:110px"] { bottom: 5.5rem !important; }

  /* BBB seal, same story on the other side: #bbb-badge is position:fixed,
     z-index:1000, bottom-left, so it lands on the sticky call bar. Lift it to
     match the chat bubble's height so the two sit level. */
  #bbb-badge { bottom: 5.5rem !important; }
}

/* BBB seal is desktop-only. The seal, the chat bubble and the sticky call bar
   were all competing for the bottom of a phone screen; the call bar wins. */
@media (max-width: 900px) { #bbb-badge { display: none !important; } }

/* ---------- Reveal animations (gated on .js so no-JS visitors see everything) ----------
   Spec §1.7: reveal must never clip content. Smaller travel + main.js marks
   anything already inside the viewport (or missed by the observer) as in. */
html.js .rv { opacity: 0; transform: translateY(16px); transition: opacity .8s var(--ease-out), transform .8s var(--ease-out); }
html.js .rv.is-in { opacity: 1; transform: none; }
.rv-d1 { transition-delay: .08s; }
.rv-d2 { transition-delay: .16s; }
.rv-d3 { transition-delay: .24s; }
.rv-d4 { transition-delay: .32s; }

/* char-split hero headline */
.split-chars .ch {
  display: inline-block;
  opacity: 0; transform: translateY(.55em) rotate(2deg);
  animation: ch-in .8s var(--ease-out) forwards;
  animation-delay: calc(var(--ci) * 28ms + .15s);
}
@keyframes ch-in { to { opacity: 1; transform: none; } }

/* ---------- Responsive ---------- */
@media (max-width: 1080px) {
  .services__grid { grid-template-columns: repeat(2, 1fr); }
  .footer__grid { grid-template-columns: 1fr 1fr; }
  .areas__grid { grid-template-columns: 1fr; }
  .rimap { max-width: 520px; }
  .related, .area-cards { grid-template-columns: repeat(2, 1fr); }
}
/* seven-item nav cannot survive below ~1100px; hand off to the burger early. Placed after
   the base .nav__burger rule so source order does not undo it. */
@media (max-width: 1100px) { .nav__links { display: none; } .nav__burger { display: block; } }
@media (max-width: 900px) {
  .nav__links { display: none; }
  .nav__burger { display: block; }
  .split { grid-template-columns: 1fr; }
  .sidecard { position: static; }
}
@media (max-width: 640px) {
  .services__grid { grid-template-columns: 1fr; }
  .svc { aspect-ratio: 3 / 3.4; }
  .form__row { grid-template-columns: 1fr; }
  .footer__grid { grid-template-columns: 1fr; gap: 2.2rem; }
  .related, .area-cards { grid-template-columns: 1fr; }
  .topbar__note span.hide-s { display: none; }
  .hero__meta { gap: .9rem 1.6rem; }
}

/* ---------- Mobile hero density (client feedback) ----------
   On a phone the top of a service page spent most of the first screen on
   chrome: a full breadcrumb trail, then an eyebrow, then the headline. The
   breadcrumb shrinks and tightens, the eyebrow goes (the H1 says the same
   thing one line later), and the one thing worth tapping gets bigger. */
@media (max-width: 640px) {
  .topbar__in a[href^="tel:"] { font-size: .92rem; letter-spacing: .04em; }
  .crumbs {
    font-size: .62rem; gap: .3rem; letter-spacing: .06em;
    margin-bottom: -.2rem;
  }
  .page-hero__in > .eyebrow { display: none; }
}

/* ---------- Touch targets (mobile) ----------
   Footer and top-bar links rendered ~19-20px tall. They cleared WCAG 2.2
   SC 2.5.8 on the spacing exemption, but sat well under the 44px comfort
   target, and the top-bar number is the only call action above the fold on a
   short phone. Grow the hit area without changing the visual type or rhythm:
   the padding absorbs the old list gap, so column height barely moves. */
@media (max-width: 900px) {
  .footer ul { gap: 0; }
  .footer ul a,
  .footer__nap a {
    display: flex; align-items: center;
    min-height: 44px;
  }
  .topbar__in a[href^="tel:"] {
    display: inline-flex; align-items: center;
    min-height: 44px; padding-inline: .25rem;
  }
  .topbar { padding-block: 0; }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .rv { opacity: 1; transform: none; }
  .split-chars .ch { opacity: 1; transform: none; animation: none; }
  .ticker__track, .reviews__row { animation: none; }
  .reviews__row { flex-wrap: wrap; width: auto; }
  .hero__gl { display: none; }
}
