/* ============================================================
   Mora Heating & Air, design system v2
   Big condensed display type, blueprint texture, copper + steel.
   Signature: the spec plate (equipment-nameplate data blocks).
   ============================================================ */

:root {
  --ink: #14181d;
  --ink-2: #1b2129;
  --steel: #222b35;
  --steel-line: #39434f;
  --copper: #c97a3a;
  --copper-deep: #9c5a26;
  --copper-tint: #f4e8db;
  --sky: #7fb0d0;
  --paper: #f8f7f2;
  --paper-2: #e9e3d6;
  --card: #ffffff;
  --line: #d6d2c6;
  --muted: #474e58;
  --on-dark: #f0f2f4;
  --on-dark-muted: #b4bdc7;

  --font-display: "Barlow Condensed", "Arial Narrow", sans-serif;
  --font-body: "Inter", -apple-system, "Segoe UI", sans-serif;
  --font-plate: "IBM Plex Mono", "Menlo", monospace;

  --text-base: clamp(1.125rem, 1.05rem + 0.35vw, 1.24rem);
  --text-h1: clamp(3.35rem, 1.9rem + 6.8vw, 7.15rem);
  --text-h2: clamp(2.2rem, 1.7rem + 2.4vw, 3.7rem);
  --text-h3: clamp(1.35rem, 1.2rem + 0.6vw, 1.65rem);

  --space-section: clamp(2.6rem, 1.9rem + 2.8vw, 4.6rem);
  --wrap: 1180px;

  --duration: 200ms;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  --grid-line: rgba(255, 255, 255, 0.045);
  --blueprint:
    repeating-linear-gradient(0deg, var(--grid-line) 0 1px, transparent 1px 56px),
    repeating-linear-gradient(90deg, var(--grid-line) 0 1px, transparent 1px 56px);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

body {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

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

a { color: var(--copper-deep); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--copper); }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--copper);
  outline-offset: 2px;
}

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 clamp(1rem, 4vw, 2rem); }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  text-wrap: balance;
}
h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); margin-bottom: 1.1rem; }
h3 { font-size: var(--text-h3); margin-bottom: 0.4rem; line-height: 1.1; }

.hl { color: var(--copper); }
.hl-sky { color: var(--sky); }

p + p { margin-top: 0.9rem; }

/* ---------- eyebrow + section heads ---------- */
.stamp {
  display: inline-block;
  font-family: var(--font-plate);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--copper-deep);
  border: 1px solid var(--copper);
  padding: 0.3rem 0.75rem;
  margin-bottom: 1.2rem;
  background: var(--copper-tint);
}
.section-dark .stamp, .hero .stamp { color: var(--copper); background: rgba(201, 122, 58, 0.08); }

.sec-head { text-align: center; max-width: 880px; margin: 0 auto 1.8rem; }
.sec-head .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  font-family: var(--font-plate);
  font-size: 0.74rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--copper-deep);
  margin-bottom: 0.9rem;
}
.sec-head .eyebrow::before, .sec-head .eyebrow::after {
  content: "";
  width: 42px;
  height: 3px;
  background: var(--copper);
}
.section-dark .sec-head .eyebrow { color: var(--copper); }
.sec-head p { color: var(--muted); max-width: 62ch; margin: 0.4rem auto 0; }
.section-dark .sec-head p { color: var(--on-dark-muted); }

/* ---------- badge pill ---------- */
.badge-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  background: rgba(201, 122, 58, 0.12);
  border: 1px solid rgba(201, 122, 58, 0.45);
  color: var(--on-dark);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.5rem 1.1rem;
  border-radius: 999px;
  margin-bottom: 1.15rem;
}
.badge-pill::before {
  content: "";
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--copper);
  box-shadow: 0 0 12px var(--copper);
}

/* ---------- header ---------- */
.site-header {
  background: var(--ink);
  color: var(--on-dark);
  border-bottom: 2px solid var(--copper);
  position: sticky;
  top: 0;
  z-index: 50;
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.65rem clamp(1rem, 4vw, 2rem);
  max-width: var(--wrap);
  margin: 0 auto;
}
.brand { display: flex; align-items: center; gap: 0.7rem; text-decoration: none; color: var(--on-dark); line-height: 1.05; }
.brand-mark { width: 44px; height: 44px; flex: none; }
.brand-text { display: flex; flex-direction: column; }
.brand-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.brand-name .mha-copper { color: var(--copper); }
.brand-geo {
  font-family: var(--font-plate);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--on-dark-muted);
  margin-top: 2px;
}
.main-nav { display: flex; align-items: center; gap: 1.4rem; }
.main-nav a {
  color: var(--on-dark);
  text-decoration: none;
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 1.02rem;
  font-weight: 600;
  padding: 0.3rem 0;
  border-bottom: 2px solid transparent;
  transition: border-color var(--duration) var(--ease), color var(--duration) var(--ease);
}
.main-nav a:hover, .main-nav a[aria-current="page"] { border-bottom-color: var(--copper); color: var(--copper); }

/* services dropdown */
.nav-drop { position: relative; }
.nav-drop-btn {
  background: none;
  border: none;
  color: var(--on-dark);
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 1.02rem;
  font-weight: 600;
  padding: 0.3rem 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  border-bottom: 2px solid transparent;
  transition: color var(--duration) var(--ease);
}
.drop-caret {
  width: 0; height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid var(--copper);
  transition: transform var(--duration) var(--ease);
}
.nav-drop:hover .nav-drop-btn, .nav-drop.open .nav-drop-btn, .nav-drop:focus-within .nav-drop-btn { color: var(--copper); }
.nav-drop:hover .drop-caret, .nav-drop.open .drop-caret { transform: rotate(180deg); }
.nav-drop-panel {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  min-width: 250px;
  background: var(--ink-2);
  border: 1px solid var(--steel-line);
  border-top: 3px solid var(--copper);
  border-radius: 0 0 6px 6px;
  box-shadow: 0 22px 48px rgba(0, 0, 0, 0.45);
  padding: 0.5rem 0;
  visibility: hidden;
  opacity: 0;
  transition: opacity var(--duration) var(--ease), transform var(--duration) var(--ease), visibility 0s linear var(--duration);
  z-index: 70;
}
.nav-drop:hover .nav-drop-panel, .nav-drop.open .nav-drop-panel, .nav-drop:focus-within .nav-drop-panel {
  visibility: visible;
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  transition: opacity var(--duration) var(--ease), transform var(--duration) var(--ease);
}
.nav-drop-panel::before {
  content: "";
  position: absolute;
  top: -14px; left: 0; right: 0; height: 14px;
}
.nav-drop-panel a {
  display: block;
  padding: 0.55rem 1.2rem;
  border-bottom: none !important;
  font-size: 1rem;
}
.nav-drop-panel a:hover { background: rgba(201, 122, 58, 0.14); color: var(--copper); }
.header-call {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: 0.03em;
  color: var(--ink);
  background: var(--copper);
  padding: 0.6rem 1.2rem;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--duration) var(--ease), transform var(--duration) var(--ease);
}
.header-call:hover { background: #dd8d4b; color: var(--ink); transform: translateY(-1px); }
.nav-toggle { display: none; }

@media (max-width: 480px) {
  .brand-name { font-size: 1.05rem; }
  .brand-geo { display: none; }
  .brand-mark { width: 34px; height: 34px; }
  .header-call { font-size: 0.95rem; padding: 0.5rem 0.75rem; }
}
@media (max-width: 980px) {
  .main-nav { display: none; }
  .nav-toggle {
    display: block;
    background: none;
    border: 1px solid var(--steel-line);
    color: var(--on-dark);
    font-family: var(--font-plate);
    font-size: 0.75rem;
    letter-spacing: 0.1em;
    padding: 0.45rem 0.7rem;
    cursor: pointer;
  }
  .main-nav.open {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--ink);
    border-bottom: 2px solid var(--copper);
    padding: 0.5rem 1.2rem 1rem;
  }
  .main-nav.open a { padding: 0.7rem 0; width: 100%; border-bottom: 1px solid var(--steel-line); }
  .main-nav.open .nav-drop { width: 100%; }
  .main-nav.open .nav-drop-btn { width: 100%; justify-content: space-between; padding: 0.7rem 0; border-bottom: 1px solid var(--steel-line); }
  .main-nav.open .nav-drop-panel {
    position: static;
    transform: none;
    visibility: visible;
    opacity: 1;
    display: none;
    box-shadow: none;
    border: none;
    border-left: 3px solid var(--copper);
    border-radius: 0;
    background: rgba(255, 255, 255, 0.03);
  }
  .main-nav.open .nav-drop.open .nav-drop-panel { display: block; }
}

/* ---------- hero ---------- */
.hero {
  background:
    radial-gradient(ellipse 900px 480px at 82% -10%, rgba(201, 122, 58, 0.16), transparent 60%),
    radial-gradient(ellipse 700px 500px at -10% 110%, rgba(127, 176, 208, 0.08), transparent 60%),
    var(--blueprint),
    linear-gradient(165deg, var(--ink-2) 0%, var(--ink) 70%);
  color: var(--on-dark);
  padding: clamp(1.2rem, 0.8rem + 1.6vw, 2.4rem) 0 calc(clamp(1.2rem, 0.8rem + 1.6vw, 2.4rem) + 1.25rem);
  position: relative;
  overflow: hidden;
  min-height: calc(100svh - 76px);
  display: grid;
  align-content: center;
}
@supports not (height: 100svh) {
  .hero { min-height: calc(100vh - 76px); }
}
.hero > .wrap { width: 100%; position: relative; z-index: 1; padding-left: clamp(2rem, 5vw, 5rem); }

/* ambient HVAC manifold gauge set, left edge, bleeds halfway off */
.hero-gauges {
  position: absolute;
  top: -4%; left: -3%;
  height: min(100svh, 1060px);
  opacity: 0.12;
  z-index: 0;
  pointer-events: none;
}
.hero-gauges svg { height: 100%; width: auto; display: block; overflow: visible; }
.gn { transform-box: view-box; }
.gnA { transform-origin: 86px 150px; animation: gaugeFlutterA 3.4s ease-in-out infinite; }
.gnB { transform-origin: 214px 150px; animation: gaugeFlutterB 2.6s ease-in-out infinite; }

/* homepage hero: left-aligned content, whole block centered on the page */
.hero-mid > .wrap { padding-left: clamp(1rem, 4vw, 2rem); }
.hero-mid .hero-inner { max-width: 900px; margin: 0 auto; transform: translateX(min(8vw, 150px)); }
.hero-mid .hero-sub { max-width: 52ch; }
@media (max-width: 900px) { .hero-mid .hero-inner { transform: none; } }
/* interior page heroes: match the homepage hero position (centered 960 box, shifted right) */
.hero:not(.hero-mid) > .wrap {
  max-width: 900px;
  width: 100%;
  margin: 0 auto;
  padding-left: clamp(1rem, 4vw, 2rem);
  padding-right: clamp(1rem, 4vw, 2rem);
  transform: translateX(min(6vw, 130px));
}
.hero:not(.hero-mid) .hero-sub { max-width: 52ch; }
@media (max-width: 900px) { .hero:not(.hero-mid) > .wrap { transform: none; } }
@keyframes gaugeFlutterA {
  0%, 100% { transform: rotate(-30deg); }
  22% { transform: rotate(-23deg); }
  48% { transform: rotate(-34deg); }
  68% { transform: rotate(-27deg); }
  86% { transform: rotate(-31deg); }
}
@keyframes gaugeFlutterB {
  0%, 100% { transform: rotate(27deg); }
  30% { transform: rotate(35deg); }
  55% { transform: rotate(21deg); }
  80% { transform: rotate(30deg); }
}
@media (prefers-reduced-motion: reduce) {
  .gnA { transform: rotate(-30deg); animation: none; }
  .gnB { transform: rotate(27deg); animation: none; }
}
@media (max-width: 820px) { .hero-gauges { display: none; } }
@keyframes lineUp { from { transform: translateY(26px); } to { transform: none; } }
.hero-lines span { animation: lineUp 500ms var(--ease) both; }
.hero-lines span:nth-child(2) { animation-delay: 90ms; }
.hero-lines span:nth-child(3) { animation-delay: 180ms; }
.hero .badge-pill { animation: lineUp 420ms var(--ease) both; }
.hero::after {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 38%;
  background: linear-gradient(115deg, transparent 0%, rgba(255, 255, 255, 0.025) 50%, transparent 100%);
  pointer-events: none;
}
.hero::before {
  content: "";
  position: absolute;
  top: 51%; right: -13%;
  width: min(86vh, 1000px);
  height: min(86vh, 1000px);
  transform: translateY(-50%);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Ccircle cx='24' cy='24' r='21' fill='none' stroke='%23c97a3a' stroke-width='1.2'/%3E%3Ccircle cx='24' cy='24' r='15.5' fill='none' stroke='%23c97a3a' stroke-width='0.5'/%3E%3Cg fill='%23c97a3a'%3E%3Cpath d='M24 24 C20 16 26 10 33 11 C30 16 28 20 24 24 Z'/%3E%3Cpath d='M24 24 C20 16 26 10 33 11 C30 16 28 20 24 24 Z' transform='rotate(120 24 24)'/%3E%3Cpath d='M24 24 C20 16 26 10 33 11 C30 16 28 20 24 24 Z' transform='rotate(240 24 24)'/%3E%3C/g%3E%3Ccircle cx='24' cy='24' r='3.4' fill='%23c97a3a'/%3E%3C/svg%3E") center / contain no-repeat;
  opacity: 0.075;
  pointer-events: none;
  z-index: 0;
  transform-origin: center;
  animation: heroFanSpin 90s linear infinite;
}
@keyframes heroFanSpin {
  from { transform: translateY(-50%) rotate(0deg); }
  to { transform: translateY(-50%) rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .hero::before { animation: none; }
}
@media (max-width: 820px) {
  .hero::before { display: none; }
  /* on a phone the hero flows to its content and clears the fixed action bar */
  .hero { min-height: auto; padding-bottom: 5.5rem; }
}
@media (max-width: 640px) {
  /* larger tap targets for dense link lists on mobile */
  .site-footer a { display: inline-block; padding: 5px 0; }
  .site-footer ul { gap: 0.7rem; }
  .city-grid a, .zip-row a { padding: 6px 2px; }
}
.hero .wrap { position: relative; z-index: 1; }
.hero h1 { max-width: 20ch; }
.hero-lines { display: block; line-height: 0.94; }
.hero-lines span { display: block; }
.hero-lines span:nth-child(4) { animation-delay: 260ms; }
.hero-sub {
  margin-top: 2.3rem;
  max-width: 58ch;
  color: var(--on-dark-muted);
  font-size: 1.2rem;
  line-height: 1.5;
}
.hero-ctas { margin-top: 1.25rem; display: flex; gap: 1rem; flex-wrap: wrap; align-items: center; }

.phone-hero { margin-top: 2.2rem; }
.phone-hero .phone-label {
  font-family: var(--font-plate);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--on-dark-muted);
}
.phone-hero a.phone-big {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.6rem, 1.7rem + 3.7vw, 4.5rem);
  letter-spacing: 0.02em;
  color: var(--copper);
  text-decoration: none;
  line-height: 1.05;
}
.phone-hero a.phone-big:hover { color: #dd8d4b; }
.phone-hero .phone-note {
  font-family: var(--font-plate);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--on-dark-muted);
  margin-top: 0.3rem;
}

.btn {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.3rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 1rem 2rem;
  text-decoration: none;
  border: 2px solid var(--copper);
  transition: background var(--duration) var(--ease), color var(--duration) var(--ease), transform var(--duration) var(--ease);
  cursor: pointer;
}
.btn:hover { transform: translateY(-2px); }
.btn-solid { background: var(--copper); color: var(--ink); }
.btn-solid:hover { background: #dd8d4b; border-color: #dd8d4b; color: var(--ink); }
.btn-ghost { background: transparent; color: var(--on-dark); }
.btn-ghost:hover { background: rgba(201, 122, 58, 0.16); color: var(--on-dark); }
.btn-ghost-dark { background: transparent; color: var(--ink); }
.btn-ghost-dark:hover { background: var(--copper-tint); color: var(--ink); }
.section-dark a.btn-solid { color: var(--ink); }
.section-dark a.btn-solid:hover { color: var(--ink); }


/* ---------- signature: spec plate ---------- */
.spec-plate {
  margin-top: clamp(1.4rem, 0.9rem + 1.6vw, 2.35rem);
  border: 1px solid var(--steel-line);
  background: rgba(255, 255, 255, 0.035);
  backdrop-filter: blur(2px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
  position: relative;
}
.spec-plate::before, .spec-plate::after,
.spec-cell:first-child::before, .spec-cell:last-child::after {
  content: "";
  position: absolute;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--steel-line);
  box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.65);
}
.spec-plate::before { top: 7px; left: 7px; }
.spec-plate::after { top: 7px; right: 7px; }
.spec-cell:first-child::before { bottom: 7px; left: 7px; top: auto; }
.spec-cell:last-child::after { bottom: 7px; right: 7px; top: auto; }


@media (max-width: 700px) {
  
  
}

/* ---------- stat row ---------- */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  gap: 1.5rem;
  margin-top: 2.2rem;
}


/* ---------- sections ---------- */
.section { padding: var(--space-section) 0; }
.section-alt { background: var(--paper-2); }
.section-dark {
  background: var(--blueprint), linear-gradient(150deg, var(--steel) 0%, var(--ink-2) 100%);
  color: var(--on-dark);
}
.section-dark h2, .section-dark h3 { color: var(--on-dark); }
.section-dark p { color: var(--on-dark-muted); }
.section-dark a { color: var(--copper); }

.lede { font-size: 1.15rem; max-width: 66ch; }

/* ---------- trust band ---------- */
.trust-band {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(ellipse 620px 300px at 8% 0%, var(--copper-tint), transparent 70%),
    var(--paper);
}
.trust-band h2 { max-width: 20ch; }
.trust-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin-top: 1.6rem;
  list-style: none;
  padding: 0;
}
.trust-chips li {
  font-family: var(--font-plate);
  font-size: 0.78rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--copper-deep);
  background: var(--copper-tint);
  border: 1px solid rgba(201, 122, 58, 0.32);
  border-radius: 999px;
  padding: 0.5rem 1rem;
}

/* ---------- team ---------- */
.team-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2rem; margin-top: 1.8rem; }
@media (max-width: 720px) {  }
.team-avatar {
  width: 150px; height: 150px; border-radius: 50%;
  border: 2px solid rgba(201, 122, 58, 0.5);
  background: radial-gradient(circle at 50% 36%, rgba(201, 122, 58, 0.22), rgba(201, 122, 58, 0.05));
  margin-bottom: 1.1rem;
  object-fit: cover;
}


/* ---------- cards ---------- */
.grid { display: grid; gap: 1.2rem; margin-top: 1.5rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(270px, 100%), 1fr)); }
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-top: 4px solid var(--copper);
  border-radius: 6px;
  padding: 1.6rem 1.5rem 1.7rem;
  box-shadow: 0 6px 18px rgba(20, 24, 29, 0.07);
  transition: transform var(--duration) var(--ease), box-shadow var(--duration) var(--ease), border-color var(--duration) var(--ease);
}
.card:hover { transform: translateY(-5px); box-shadow: 0 18px 38px rgba(20, 24, 29, 0.14); border-color: var(--copper); }
.card:has(.tag) { display: flex; flex-direction: column; }
.card .tag { margin-top: auto; align-self: flex-start; }
.card .card-icon { width: 44px; height: 44px; margin-bottom: 0.9rem; color: var(--copper-deep); }
.card h3 { margin-bottom: 0.5rem; }
.card p { color: var(--muted); font-size: 0.95rem; }
.card a.card-link {
  display: inline-block;
  margin-top: 0.9rem;
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 700;
  font-size: 1rem;
}
.section-dark .card { background: rgba(255, 255, 255, 0.045); border-color: var(--steel-line); }
.section-dark .card:hover { box-shadow: 0 14px 30px rgba(0, 0, 0, 0.35); }
.section-dark .card p { color: var(--on-dark-muted); }


/* ---------- numbered steps ---------- */
.steps { counter-reset: step; margin-top: 2rem; display: grid; gap: 1.3rem; }
.step { display: grid; grid-template-columns: 3.4rem 1fr; gap: 1.2rem; align-items: start; }
.step::before {
  counter-increment: step;
  content: counter(step);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.5rem;
  color: var(--ink);
  background: var(--copper);
  border-radius: 50%;
  width: 3.4rem; height: 3.4rem;
  display: grid; place-items: center;
}
.step h3 { margin-bottom: 0.25rem; }
.step p { color: var(--muted); font-size: 0.97rem; }
.section-dark .step p { color: var(--on-dark-muted); }

/* ---------- FAQ: card accordions ---------- */
.faq { margin-top: 0.6rem; max-width: 900px; margin-left: auto; margin-right: auto; display: grid; gap: 0.7rem; }
.faq details {
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: 6px;
  box-shadow: 0 4px 14px rgba(20, 24, 29, 0.06);
  transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
}
.faq details:hover { border-color: var(--copper); box-shadow: 0 10px 24px rgba(20, 24, 29, 0.1); }
.faq details[open] { border-left-color: var(--copper); }
.faq summary {
  cursor: pointer;
  list-style: none;
  padding: 1.1rem 3.4rem 1.1rem 1.2rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.35rem;
  text-transform: none;
  position: relative;
  user-select: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  position: absolute;
  right: 0.9rem; top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-plate);
  color: var(--card);
  background: var(--copper);
  width: 1.7rem; height: 1.7rem;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: 1.15rem;
  line-height: 1;
  transition: transform var(--duration) var(--ease), background var(--duration) var(--ease);
}
.faq details[open] summary::after { content: "\2212"; background: var(--ink); transform: translateY(-50%) rotate(180deg); }
@keyframes faqIn { from { transform: translateY(-6px); } to { transform: none; } }
.faq .faq-a { padding: 0 1.2rem 1.25rem; color: var(--muted); max-width: 72ch; }
.faq details[open] .faq-a { animation: faqIn 220ms var(--ease); }

/* ---------- checklist ---------- */
.checklist { margin: 1.3rem 0 0 0; list-style: none; display: grid; gap: 0.6rem; }
.checklist li { padding-left: 1.8rem; position: relative; }
.checklist li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.42em;
  width: 0.75em; height: 0.75em;
  background: var(--copper);
  clip-path: polygon(14% 44%, 0 62%, 40% 100%, 100% 16%, 84% 2%, 39% 70%);
}

/* ---------- diagnosis tag (symptom cause cards) ---------- */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-top: 1rem;
  font-family: var(--font-plate);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.35rem 0.7rem;
  border-radius: 3px;
  font-weight: 500;
}
.tag::before { content: ""; width: 7px; height: 7px; border-radius: 50%; flex: none; }
.tag-diy { background: #e8f0e6; color: #2f5d2a; border: 1px solid #b9d3b3; }
.tag-diy::before { background: #4b8c42; }
.tag-pro { background: var(--copper-tint); color: var(--copper-deep); border: 1px solid #e0bd9c; }
.tag-pro::before { background: var(--copper); }

/* ---------- symptom link cards ---------- */
.symptom-grid { display: grid; gap: 0.9rem; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); margin-top: 1.6rem; }
.symptom-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 4px solid var(--copper);
  border-radius: 5px;
  padding: 1rem 1.2rem;
  text-decoration: none;
  color: var(--ink);
  font-weight: 500;
  box-shadow: 0 4px 12px rgba(20, 24, 29, 0.05);
  transition: transform var(--duration) var(--ease), box-shadow var(--duration) var(--ease), border-left-color var(--duration) var(--ease);
}
.symptom-link:hover { transform: translateX(5px); box-shadow: 0 10px 24px rgba(20, 24, 29, 0.11); color: var(--ink); border-left-color: var(--ink); }
.symptom-link::after {
  content: "\2192";
  font-family: var(--font-plate);
  color: var(--copper-deep);
  font-size: 1.1rem;
  flex: none;
  transition: transform var(--duration) var(--ease);
}
.symptom-link:hover::after { transform: translateX(4px); }

/* ---------- scroll reveal ---------- */
@media (prefers-reduced-motion: no-preference) {
  html:not(.no-js) .reveal { opacity: 0; transform: translateY(18px); transition: opacity 600ms var(--ease), transform 600ms var(--ease); }
  html:not(.no-js) .reveal.in { opacity: 1; transform: none; }
}

/* ---------- footer mark ---------- */
.footer-brand { display: flex; align-items: center; gap: 0.8rem; margin-bottom: 2rem; }
.footer-brand svg { width: 40px; height: 40px; flex: none; }
/* ⛔ THE FOOTER BADGE, added 2026-08-15 on Jay's instruction. The header keeps its small
   mark; this is the full circular badge and it appears in the footer only. 96px is large
   enough that the ring wording is legible without the badge dominating the column. */
.footer-badge { width: 140px; height: 140px; flex: none; display: block; }
@media (max-width: 700px) { .footer-badge { width: 104px; height: 104px; } }
.footer-brand .brand-name { font-family: var(--font-display); font-weight: 700; font-size: 1.4rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--on-dark); }
.footer-brand .mha-copper { color: var(--copper); }

/* ---------- callout ---------- */
.callout {
  background: var(--ink-2);
  color: var(--on-dark);
  border-left: 4px solid var(--copper);
  padding: 1.3rem 1.5rem;
  margin-top: 2rem;
  border-radius: 4px;
}


/* ---------- two-path split ---------- */
.path-split { display: grid; gap: 1.3rem; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); margin-top: 2.2rem; }

.path:hover { transform: translateY(-4px); box-shadow: 0 16px 34px rgba(20, 24, 29, 0.1); }


/* ---------- forms ---------- */
.form-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-top: 4px solid var(--copper);
  box-shadow: 0 24px 60px rgba(20, 24, 29, 0.12);
  padding: clamp(1.4rem, 3vw, 2.4rem);
  max-width: 760px;
}


label { font-weight: 600; font-size: 0.9rem; display: block; margin-bottom: 0.35rem; }
input, select, textarea {
  width: 100%;
  font: inherit;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  border-radius: 3px;
}
textarea { min-height: 130px; resize: vertical; }
@media (max-width: 640px) {  }

/* ---------- footer ---------- */
.site-footer {
  background: var(--blueprint), var(--ink);
  color: var(--on-dark-muted);
  padding: 3.8rem 0 2.2rem;
  border-top: 3px solid var(--copper);
  font-size: 0.92rem;
}
@media (max-width: 640px) {
  .site-footer > .wrap { padding-left: 1.5rem; padding-right: 1.5rem; }
}
/* only pad above the footer when the preceding block is a light section */
main > section:last-child:not(.section-dark) + .site-footer,
main:has(> section:last-child:not(.section-dark)) + .site-footer { margin-top: 0; }
.footer-grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); }

.site-footer ul { list-style: none; margin-top: 0.8rem; display: grid; gap: 0.45rem; }
.site-footer a { color: var(--on-dark-muted); text-decoration: none; }
.site-footer a:hover { color: var(--copper); }
.footer-plate {
  margin-top: 2.6rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--steel-line);
  font-family: var(--font-plate);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  line-height: 2;
  color: var(--on-dark-muted);
}

/* ---------- mobile sticky CTA ---------- */
.sticky-cta {
  display: none;
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 60;
  background: var(--ink);
  border-top: 2px solid var(--copper);
}
.sticky-cta a {
  flex: 1;
  text-align: center;
  padding: 0.95rem 0.3rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-decoration: none;
  color: var(--on-dark);
}
.sticky-cta a.cta-call { background: var(--copper); color: var(--ink); }
.sticky-cta a + a { border-left: 1px solid var(--steel-line); }
@media (max-width: 820px) {
  .sticky-cta { display: flex; }
  body { padding-bottom: 64px; }
}

/* ---------- breadcrumbs ---------- */
.crumbs { font-size: 0.82rem; color: var(--muted); padding: 0.9rem 0 0; }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--copper-deep); }

/* ---------- utility ---------- */
.mt-1 { margin-top: 1rem; }
.mt-2 { margin-top: 2rem; }
.center { text-align: center; }
.zip-row { display: flex; flex-wrap: wrap; gap: 0.55rem; margin-top: 1.2rem; }
.zip-chip {
  font-family: var(--font-plate);
  font-size: 0.82rem;
  border: 1px solid var(--line);
  background: var(--card);
  padding: 0.35rem 0.8rem;
  text-decoration: none;
  color: var(--ink);
  transition: border-color var(--duration) var(--ease), transform var(--duration) var(--ease);
}
.zip-chip:hover { border-color: var(--copper); color: var(--copper-deep); transform: translateY(-2px); }


.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--copper);
  color: var(--ink);
  padding: 0.6rem 1rem;
  z-index: 100;
}
.skip-link:focus { left: 0; }

/* ---------- diagrams ---------- */
/* No HVAC photography exists yet and stock photos are a roll-up tell, so these
   carry the visual weight. Colors are CSS-driven, not baked into the SVG, so
   one diagram reads correctly on both the light and the dark sections. */
.diagram {
  margin: 2.2rem 0 1.6rem;
  padding: 1.5rem 1.2rem 1.1rem;
  border: 1px solid var(--steel-line);
  border-radius: 6px;
}
.diagram-svg { display: block; width: 100%; height: auto; overflow: visible; }


.diagram figcaption {
  margin-top: 1.1rem;
  font-family: var(--font-plate);
  font-size: 0.76rem;
  letter-spacing: 0.04em;
  line-height: 1.7;
  text-align: center;
}

/* light sections: dark ink on a faint copper wash */
.section-alt .diagram, .section .diagram {
  background: rgba(201, 122, 58, 0.05);
  border-color: rgba(20, 24, 29, 0.16);
}

.section-alt .diagram figcaption, .section .diagram figcaption { color: #4a5560; }

/* dark sections: muted steel on near-black */
.section-dark .diagram { background: rgba(20, 24, 29, 0.55); border-color: var(--steel-line); }


/* SVG text scales with the viewBox, so a font-size bump here does nothing.
   The wide diagram is swapped for a stacked one instead. */
.dg-tall { display: none; }
@media (max-width: 700px) {
  .diagram { padding: 1rem 0.6rem 0.8rem; }
  .diagram figcaption { font-size: 0.72rem; text-align: left; }
  .dg-wide { display: none; }
  .dg-tall { display: block; max-width: 340px; margin: 0 auto; }
}

/* ---------- guides + areas grids ---------- */
.guides-grid, .areas-grid { display: grid; gap: 0.9rem; }
.guides-grid { grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); }


.guide-card, .area-card {
  display: block;
  text-decoration: none;
  border: 1px solid var(--steel-line);
  border-radius: 5px;
  padding: 1.1rem 1.1rem 1rem;
  background: rgba(201, 122, 58, 0.04);
  transition: border-color 160ms var(--ease), transform 160ms var(--ease),
              background 160ms var(--ease);
}
.guide-card:hover, .area-card:hover,
.guide-card:focus-visible, .area-card:focus-visible {
  border-color: var(--copper);
  background: rgba(201, 122, 58, 0.09);
  transform: translateY(-2px);
}
.guide-card:focus-visible, .area-card:focus-visible {
  outline: 2px solid var(--copper); outline-offset: 2px;
}
.guide-kicker, .area-sub {
  display: block;
  font-family: var(--font-plate);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--copper);
}
.guide-card h3 {
  margin: 0.5rem 0 0.7rem;
  font-size: 1.02rem;
  line-height: 1.28;
  color: var(--ink);
}
.guide-more {
  font-family: var(--font-plate);
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  opacity: 0.62;
}

.area-name {
  display: block;
  font-family: var(--font-display);
  font-size: 1.02rem;
  letter-spacing: 0.01em;
  color: var(--ink);
}


.section-dark .guide-card h3, .section-dark .area-name { color: var(--on-dark); }
.section-dark .guide-more { color: var(--on-dark); }

/* GoHighLevel embedded forms.
   The form itself is transparent, so it needs a light surface underneath. On
   section-dark the form's own dark labels would otherwise sit on dark ink and
   disappear, which is exactly what happened on /second-opinion. */
.ghl-form {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: clamp(0.75rem, 0.4rem + 1.2vw, 1.75rem);
  max-width: 780px;
  margin: 2rem auto 0;
}
.ghl-form iframe { display: block; width: 100%; border: 0; }

/* Intake form inside the closing CTA band. The band is dark, the form is not,
   so the heading and lede stay on-dark and the form sits on its own light card. */
.band-form { margin-top: clamp(2rem, 1.4rem + 2vw, 3.25rem); }
.band-form h3 {
  color: var(--on-dark);
  font-family: var(--font-display);
  font-size: var(--text-h3);
  text-align: center;
  margin: 0 0 0.4rem;
}
.band-form > p {
  color: var(--on-dark-muted);
  text-align: center;
  max-width: 46ch;
  margin: 0 auto;
}

/* =========================================================================
   DESIGN PASS 2026-08-13
   The site read as a well-written document rather than a designed page. The
   causes were measurable, not matters of taste: prose ran the full 1180px
   wrap (110-120 characters a line against an optimal 60-75), the signature
   hero artwork sat at 7 to 12 percent opacity, and every one of 288 pages
   used that same artwork so it stopped signalling anything.
   ========================================================================= */

/* ---------- reading measure ----------
   Body prose gets a real measure. Grids, diagrams, and forms are untouched,
   so only the text that is meant to be read is constrained. */
.section > .wrap > p,
.section > .wrap > ul:not([class]),
.section > .wrap > ol:not([class]),
.section > .wrap > .sec-head + p {
  max-width: 68ch;
}
.section > .wrap > p.lede { max-width: 62ch; }
/* Centred section heads keep their own narrower measure and stay centred. */
.sec-head p { max-width: 58ch; }

/* ---------- hero artwork: anchored, and actually visible ----------
   Was top:-4% with a fixed height, so the manifold floated and stopped
   mid-section instead of meeting the bottom edge. Now it sits on the floor of
   the hero and runs the full height of it. Opacity raised from 0.12 to a value
   where the linework reads as intended artwork rather than a smudge. */
.hero-gauges {
  top: auto;
  bottom: 0;
  height: min(92%, 1060px);
  opacity: 0.30;
}
.hero::before { opacity: 0.16; }

/* Interior pages get the quiet variant. The homepage keeps the full
   composition, which is the one that earns its place. */
.hero:not(.hero-mid) .hero-gauges { opacity: 0.18; height: min(78%, 780px); }
.hero:not(.hero-mid)::before { opacity: 0.09; }

/* ---------- button contrast ----------
   .btn-ghost paints near-white text for dark sections. On a light section it
   rendered white on cream and was invisible. Anything outside a dark section
   falls back to ink so a mislabelled button can never disappear again. */
.btn-ghost { color: var(--ink); }
.btn-ghost:hover { background: var(--copper-tint); color: var(--ink); }
.section-dark .btn-ghost, .hero .btn-ghost, .footer .btn-ghost { color: var(--on-dark); }
.section-dark .btn-ghost:hover, .hero .btn-ghost:hover {
  background: rgba(201, 122, 58, 0.16); color: var(--on-dark);
}

/* ---------- proof row (replaces the spec plate) ----------
   The old treatment was four monospace cells inside a hairline box with fake
   screw heads in the corners. Jay's call: the box is bland and the skeuomorphic
   screws read as cheap. The four facts are worth keeping, so they become a
   typographic row instead of a terminal readout: no container, real body type,
   a copper rule marking each item, and a value that carries actual weight. */
.proof-row {
  margin-top: clamp(1.5rem, 1rem + 1.8vw, 2.6rem);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  gap: clamp(1.1rem, 0.7rem + 1.4vw, 2.2rem);
  max-width: 940px;
}
.proof-item { position: relative; padding-top: 0.85rem; }
.proof-item::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 30px; height: 2px;
  background: var(--copper);
}
.proof-k {
  display: block;
  font-family: var(--font-plate);
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--copper);
  margin-bottom: 0.35rem;
}
.proof-v {
  display: block;
  font-family: var(--font-body);
  font-size: clamp(0.95rem, 0.9rem + 0.2vw, 1.06rem);
  font-weight: 500;
  line-height: 1.35;
  color: var(--on-dark);
}

@media (max-width: 560px) {
  .proof-row { grid-template-columns: 1fr 1fr; gap: 1.1rem; }
}

/* ---------- hero deck ----------
   The subhead was a <strong> line and a lighter block jammed into one
   paragraph with a <br>, so the leading did not match and it read as two
   half-finished thoughts. Two elements now, with a real size step between. */
.hero-deck {
  font-size: clamp(1.18rem, 1.05rem + 0.55vw, 1.5rem);
  font-weight: 600;
  line-height: 1.32;
  color: var(--on-dark);
  max-width: 30ch;
  margin: 0 0 0.7rem;
}
.hero-sub { margin-top: 0; }

/* One primary action. The phone is it. The form link is plainly secondary
   instead of an outlined button competing with a 3rem phone number. */
.hero-alt-cta {
  border: 0;
  padding-left: 0;
  text-decoration: underline;
  text-underline-offset: 4px;
  font-size: 0.95rem;
  opacity: 0.82;
}
.hero-alt-cta:hover { background: transparent; opacity: 1; }

/* ---------- interior heroes: not the homepage ----------
   Every one of 288 pages carried the identical gauge-and-fan composition, so
   the signature became wallpaper and nothing distinguished one page from
   another. The homepage keeps it. Interior pages get a compact hero with only
   a slim edge motif, which also reclaims roughly 500px of dead space. */
.hero:not(.hero-mid) {
  min-height: 0;
  padding-top: clamp(2.4rem, 1.6rem + 3vw, 4.5rem);
  padding-bottom: clamp(2.4rem, 1.6rem + 3vw, 4.5rem);
}
.hero:not(.hero-mid)::before { display: none; }
.hero:not(.hero-mid) .hero-gauges {
  height: min(100%, 460px);
  opacity: 0.14;
  left: -8%;
}
/* A copper hairline down the left edge marks interior pages as a set without
   repeating the homepage artwork. */
.hero:not(.hero-mid)::after {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: linear-gradient(180deg, var(--copper) 0%, transparent 85%);
  opacity: 0.75;
}

/* Interior hero refinements.
   The half-cropped gauge at the left edge read as a rendering mistake rather
   than a deliberate crop, so interior pages drop the artwork entirely. The
   copper edge rule plus the blueprint grid is enough to mark them as a set,
   and it is genuinely different from the homepage instead of a faded copy. */
.hero:not(.hero-mid) .hero-gauges { display: none; }
.hero:not(.hero-mid) h1 { margin-bottom: 1.15rem; }
.hero:not(.hero-mid) .hero-sub { margin-bottom: 0; }

/* ---------- domino diagram, rebuilt 2026-08-13 ----------
   Was three empty rounded rectangles with X marks, an equals sign, and two
   arrows: abstract wireframe filler, beige on beige, nothing recognisably HVAC.
   It is the most important graphic on the site because it IS the positioning,
   so it now draws a real failure chain: clogged filter, starved air, iced coil,
   flooded compressor. Value contrast does the arguing. The cheap CAUSE is
   copper and heavy; the expensive VICTIM everyone else replaces is outlined and
   quiet. That reversal is the whole point. */
.diagram { margin: clamp(1.6rem, 1rem + 2vw, 2.8rem) 0; }
.diagram-svg { width: 100%; height: auto; display: block; }

.dg-part { fill: none; stroke: var(--steel-line); stroke-width: 2; }
.dg-cause .dg-part { stroke: var(--copper); stroke-width: 3; }
.dg-victim .dg-part { stroke: var(--muted); stroke-width: 2; }

.dg-pleat { stroke: var(--line); stroke-width: 1; fill: none; }
.dg-clog { fill: var(--copper); opacity: 0.22; stroke: none; }
.dg-blade { fill: var(--steel-line); opacity: 0.5; stroke: none; }
.dg-hub { fill: var(--steel-line); stroke: none; }
.dg-coil { stroke: var(--steel-line); stroke-width: 1.5; fill: none; }
.dg-ice { stroke: var(--sky); stroke-width: 1.6; fill: none; stroke-linecap: round; }
.dg-bolt { stroke: var(--copper); stroke-width: 2.4; fill: none;
           stroke-linejoin: round; stroke-linecap: round; }

.dg-flow path { stroke: var(--muted); stroke-width: 1.6; fill: none; }
.dg-head { stroke: var(--muted); stroke-width: 1.6; fill: none;
           stroke-linecap: round; stroke-linejoin: round; }

.dg-step {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  fill: var(--copper);
  opacity: 0.55;
}
.dg-name {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.04em;
  fill: var(--ink);
  text-anchor: middle;
}
.dg-tall .dg-name, .dg-tall .dg-note, .dg-tall .dg-rel { text-anchor: start; }
.dg-cause .dg-name { fill: var(--copper-deep); }
.dg-note {
  font-family: var(--font-body);
  font-size: 12.5px;
  fill: var(--muted);
  text-anchor: middle;
}
.dg-rel {
  font-family: var(--font-plate);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  fill: var(--muted);
  text-anchor: middle;
}
.dg-loop { stroke: var(--copper); stroke-width: 1.6; fill: none;
           stroke-dasharray: 5 5; opacity: 0.75; }
.dg-loop-head { stroke: var(--copper); opacity: 0.75; }
.dg-conclusion {
  font-family: var(--font-body);
  font-size: 13.5px;
  font-style: italic;
  fill: var(--copper-deep);
  text-anchor: middle;
}
.dg-tall .dg-conclusion { text-anchor: start; font-size: 15px; }
.diagram figcaption {
  margin-top: 0.9rem;
  font-size: 0.95rem;
  color: var(--muted);
  max-width: 60ch;
}

/* Wide on desktop, stacked on a phone. SVG text scales with the viewBox, so the
   wide labels would render at about 6px on a 390px screen. */
.dg-tall { display: none; }
@media (max-width: 720px) {
  .dg-wide { display: none; }
  .dg-tall { display: block; }
}

/* The figcaption was inheriting the old monospace, centred treatment, which
   read as a terminal readout under a technical illustration. It is prose, so
   it gets prose type. It also no longer repeats the line inside the diagram. */
.diagram figcaption {
  font-family: var(--font-body);
  font-size: 0.98rem;
  letter-spacing: 0;
  line-height: 1.55;
  text-align: left;
  margin-top: 1rem;
  max-width: 62ch;
}
@media (max-width: 700px) { .diagram figcaption { font-size: 0.95rem; } }

/* ---------- embedded form loading state ----------
   The 640px iframe box sat completely blank while the third-party widget
   booted, so a sub-two-second wait felt much longer than it was. A skeleton
   occupies the space and the real form fades in over it. */
.ghl-form { position: relative; }
.ghl-skeleton {
  position: absolute;
  inset: clamp(0.75rem, 0.4rem + 1.2vw, 1.75rem);
  display: grid;
  align-content: start;
  gap: 1.4rem;
  pointer-events: none;
}
.ghl-skeleton span {
  display: block;
  height: 42px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--paper-2) 25%, var(--paper) 50%, var(--paper-2) 75%);
  background-size: 260% 100%;
  animation: skeletonSweep 1.35s ease-in-out infinite;
}
.ghl-skeleton span:first-child { max-width: 55%; height: 16px; }
@keyframes skeletonSweep {
  from { background-position: 130% 0; }
  to   { background-position: -130% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .ghl-skeleton span { animation: none; }
}
.ghl-form iframe { opacity: 0; transition: opacity 260ms var(--ease); }
.ghl-form iframe.is-ready { opacity: 1; }
/* No JavaScript means no observer and no fade, so the iframe must stay visible. */
.no-js .ghl-form iframe { opacity: 1; }

/* =========================================================================
   CARD GRIDS REBUILT 2026-08-13
   Both were `auto-fit minmax()` grids: every item identical weight, no
   hierarchy, and orphan last rows (two cards stranded in a six-wide row, two
   in a four-wide row). That is the default-card-grid pattern banned in
   rules/web/design-quality.md. Replaced with compositions that carry hierarchy
   and, in the service area, real information instead of a repeated label.
   ========================================================================= */

/* ---------- service area: editorial index ---------- */
.areas-index {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: clamp(1.6rem, 1rem + 3vw, 4rem);
  margin-top: 1.6rem;
  align-items: start;
}
.area-head {
  font-family: var(--font-plate);
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--copper);
  margin: 0 0 0.2rem;
  padding-bottom: 0.7rem;
  border-bottom: 2px solid var(--ink);
}

.area-list { display: flex; flex-direction: column; }
.area-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.2rem;
  padding: 0.72rem 0.2rem 0.72rem 0;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  position: relative;
  transition: padding-left var(--duration) var(--ease),
              background var(--duration) var(--ease);
}

.area-row::before {
  content: "";
  position: absolute;
  left: 0; top: 50%;
  width: 0; height: 2px;
  background: var(--copper);
  transform: translateY(-50%);
  transition: width var(--duration) var(--ease);
}
.area-row:hover, .area-row:focus-visible {
  padding-left: 1.5rem;
  background: linear-gradient(90deg, rgba(201, 122, 58, 0.08), transparent 65%);
  outline: none;
}
.area-row:hover::before, .area-row:focus-visible::before { width: 1rem; }
.area-name {
  font-family: var(--font-display);
  font-size: clamp(1.12rem, 1rem + 0.5vw, 1.4rem);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--ink);
  line-height: 1.1;
}

.area-row:hover .area-name { color: var(--copper-deep); }
.section-dark .area-row:hover .area-name { color: var(--copper); }
.area-zips {
  font-family: var(--font-plate);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  color: var(--muted);
  text-align: right;
  white-space: nowrap;
}

@media (max-width: 760px) {
  .areas-index { grid-template-columns: 1fr; gap: 2rem; }
  .area-zips { font-size: 0.64rem; }
}
@media (max-width: 420px) {
  .area-row { flex-direction: column; align-items: flex-start; gap: 0.15rem; }
  .area-zips { text-align: left; }
}

/* ---------- guides: bento, one featured ---------- */
.guides-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  margin-top: 1.4rem;
}
.guide-feature { grid-column: span 2; grid-row: span 2; }
.guide-card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: clamp(1.1rem, 0.8rem + 1vw, 1.7rem);
  border: 1px solid var(--steel-line);
  border-radius: 3px;
  text-decoration: none;
  background: rgba(255, 255, 255, 0.02);
  transition: border-color var(--duration) var(--ease),
              background var(--duration) var(--ease),
              transform var(--duration) var(--ease);
}
.guide-card:hover, .guide-card:focus-visible {
  border-color: var(--copper);
  background: rgba(201, 122, 58, 0.07);
  transform: translateY(-2px);
  outline: none;
}
.guide-card h3 {
  font-size: clamp(1.02rem, 0.95rem + 0.3vw, 1.22rem);
  line-height: 1.15;
  margin: 0;
  color: var(--on-dark);
}
.guide-feature h3 {
  font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2.5rem);
  line-height: 1.05;
}
.guide-blurb {
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--on-dark-muted);
  margin: 0.15rem 0 0;
  max-width: 46ch;
}
.guide-card:not(.guide-feature) .guide-blurb { display: none; }
.guide-more { margin-top: auto; padding-top: 0.7rem; }
.guide-feature .guide-more { font-size: 0.9rem; }
@media (max-width: 860px) {
  .guides-grid { grid-template-columns: repeat(2, 1fr); }
  .guide-feature { grid-column: span 2; grid-row: span 1; }
}
@media (max-width: 520px) {
  .guides-grid { grid-template-columns: 1fr; }
  .guide-feature { grid-column: span 1; }
}

/* One service area, one column. The second column existed only while a
   second county list sat beside it; with that list gone, a two-column grid
   left half the section empty. The city cards flow to fill the width. */
.areas-index { grid-template-columns: 1fr; }
.area-col-wide .area-list { column-count: 2; column-gap: clamp(1.4rem, 1rem + 2vw, 3rem); }
.area-col-wide .area-row { break-inside: avoid; }
@media (max-width: 900px) {
  .areas-index { grid-template-columns: 1fr; }
  .area-col-wide .area-list { column-count: 2; }
}
@media (max-width: 560px) {
  .area-col-wide .area-list { column-count: 1; }
}

/* CSS columns are ignored on a flex container, so the wide list has to leave
   flex behind. .area-row is already a flex item itself, which is what actually
   lays each row out, so nothing is lost. */
.area-col-wide .area-list { display: block; }
.area-col-wide .area-row { display: flex; width: 100%; }

/* =========================================================================
   MOBILE LEGIBILITY PASS 2026-08-13
   Measured with scripts/checks/mobile_audit.py at 390x844, not eyeballed.
   The audience is homeowners who are frequently older and often wearing
   reading glasses, on a phone, usually while something in the house is
   broken. Small type is not a style choice there, it is a lost call.

   Floors applied: nothing under 14px anywhere, body copy 17px, secondary 15px,
   tap targets 44x44, contrast 4.5:1 for normal text.
   ========================================================================= */

/* ---------- contrast, at every width ----------
   Copper on paper measured 3.09:1 for the stamp and 4.21:1 for inline links,
   both under the 4.5:1 floor. copper-deep on paper measures about 5:1. On dark
   sections the original copper already passes, so it is kept there. */
.section .stamp, .section-alt .stamp, .hero:not(.hero-mid) .stamp { color: var(--copper-deep); }
.section .eyebrow, .section-alt .eyebrow { color: var(--copper-deep); }
.section a:not(.btn):not(.card-link):not(.area-row):not(.guide-card),
.section-alt a:not(.btn):not(.card-link):not(.area-row):not(.guide-card) {
  color: var(--copper-deep);
}
.section-dark .stamp, .section-dark .eyebrow, .hero-mid .stamp { color: var(--copper); }

/* ---------- type floors on phones ---------- */
@media (max-width: 720px) {
  /* Nothing on the page may render under 14px. These were 9.6 to 13.1. */
  .stamp, .eyebrow { font-size: 0.9rem; letter-spacing: 0.12em; }
  .proof-k { font-size: 0.82rem; letter-spacing: 0.14em; }
  .badge-pill { font-size: 0.88rem; }
  .phone-note { font-size: 0.9rem; }
  .crumbs { font-size: 0.9rem; }
  .nav-toggle { font-size: 0.95rem; }
  .guide-kicker, .guide-more, .area-zips { font-size: 0.85rem; }

  /* Body copy. Cards and process steps measured 15.2 and 15.5px. */
  body { font-size: 1.06rem; }
  .card p, .step p, .guide-blurb, .checklist li, .faq .faq-a,
  .section > .wrap > p, .section > .wrap > li { font-size: 1.06rem; }
  .lede { font-size: 1.14rem; }
  .proof-v { font-size: 1.02rem; }

  /* Leading matters more than size for tired eyes. */
  p, li { line-height: 1.6; }
  .hero-deck { line-height: 1.45; }
  .hero-sub { line-height: 1.58; }

  /* ---------- tap targets ----------
     Header brand 156x35, MENU 58x31, phone 112x41, footer links 69x34 and
     breadcrumbs 37x16 were all under the 44px minimum. */
  .nav-toggle { min-height: 44px; min-width: 60px; padding: 0.6rem 0.9rem; }
  .header-call { min-height: 44px; display: inline-flex; align-items: center; }
  .brand { min-height: 44px; display: flex; align-items: center; }
  .footer-grid a, .footer-grid li > a {
    display: inline-block;
    padding: 0.55rem 0;
    min-height: 44px;
    line-height: 1.55;
    font-size: 1rem;
  }
  .crumbs a { display: inline-block; padding: 0.5rem 0; min-height: 40px; }
  .card-link, .guide-more { display: inline-block; padding: 0.5rem 0; min-height: 44px; }
  .area-row { padding-top: 0.95rem; padding-bottom: 0.95rem; }

  /* Reading measure on a phone: 45 to 60 characters is the comfortable band. */
  .section > .wrap > p, .section > .wrap > ul, .lede { max-width: 100%; }
}

/* ---------- diagram labels on phones ----------
   SVG text scales with the viewBox, so the stacked variant's labels were
   rendering at 11 to 12.5px on a 390px screen. Sizes are set against the
   340-unit viewBox, so these values are viewBox units, not px. */
.dg-tall .dg-name { font-size: 17px; }
.dg-tall .dg-note { font-size: 14.5px; }
.dg-tall .dg-rel { font-size: 13px; }
.dg-tall .dg-conclusion { font-size: 16px; }

/* ---------- mobile pass, round two ----------
   Round one missed on three counts, all caught by re-running the audit rather
   than assuming: several rules had higher specificity than the ones I wrote,
   rem is root-relative so 0.82rem is still 13.1px, and setting copper-deep on
   interior hero stamps made contrast WORSE because those heroes are dark. */

/* Interior heroes are dark. Bright copper is correct there; copper-deep is not. */
.hero .stamp, .hero .eyebrow { color: var(--copper) !important; }

/* The big phone number measured 2.84:1 against the dark band, just under the
   3.0 floor for large text. A lighter copper clears it without changing the
   brand read. */
.phone-hero a.phone-big { color: #e08a45; }
.phone-hero a.phone-big:hover { color: #f0a05f; }

@media (max-width: 720px) {
  /* Beat the more specific rules that survived round one. */
  .sec-head .eyebrow { font-size: 0.92rem; letter-spacing: 0.12em; }
  .phone-hero .phone-label,
  .phone-hero .phone-note { font-size: 0.94rem; letter-spacing: 0.08em; }
  .proof-k { font-size: 0.9rem; }
  .footer-plate, .footer-plate * { font-size: 0.94rem; line-height: 1.6; }

  /* Checklist links were 207x20 tap targets and inherited the base link colour. */
  .checklist li { padding-top: 0.35rem; padding-bottom: 0.35rem; }
  .checklist li a {
    display: inline-block;
    padding: 0.5rem 0;
    min-height: 44px;
    font-size: 1.04rem;
    color: var(--copper-deep);
  }
  

  /* Breadcrumbs: 40px was close but still short of the 44px floor. */
  .crumbs a { min-height: 44px; padding: 0.62rem 0; }
  .crumbs { font-size: 0.94rem; }
  .stamp, .eyebrow { font-size: 0.94rem; }
  .guide-kicker, .guide-more, .area-zips { font-size: 0.9rem; }
}

/* ---------- mobile pass, round three ----------
   Round two's link rule was too broad. `.section-dark` carries BOTH classes, so
   `.section a` was repainting links inside dark bands with the dark-on-light
   colour, which is how the big phone number ended up at 2.84:1 against the ink
   background. Scoped to light sections only.

   Also: copper-deep clears 4.5:1 on --paper but only reaches 4.21:1 on the
   slightly darker --paper-2 used by `.section-alt`, so that surface gets a
   deeper tone again. */
:root { --copper-ink: #8a4e20; }

.section a:not(.btn):not(.card-link):not(.area-row):not(.guide-card),
.section-alt a:not(.btn):not(.card-link):not(.area-row):not(.guide-card) {
  color: inherit;
}
.section:not(.section-dark) a:not(.btn):not(.card-link):not(.area-row):not(.guide-card) {
  color: var(--copper-deep);
}
.section-alt:not(.section-dark) a:not(.btn):not(.card-link):not(.area-row):not(.guide-card) {
  color: var(--copper-ink);
}
.section-dark a:not(.btn):not(.card-link):not(.area-row):not(.guide-card) {
  color: var(--copper);
}
.section-dark .phone-hero a.phone-big,
.phone-hero a.phone-big { color: #e08a45; }
.phone-hero a.phone-big:hover { color: #f2a462; }

@media (max-width: 720px) {
  /* Clear the 15px secondary floor rather than sitting a fraction under it. */
  .proof-k { font-size: 0.96rem; }
  .sec-head .eyebrow, .stamp, .eyebrow { font-size: 0.96rem; }
  .section-alt:not(.section-dark) .checklist li a { color: var(--copper-ink); }
  /* Trailing "see everything" links were 302x20 tap targets. */
  .mt-2 a, p.mt-2 > a {
    display: inline-block;
    padding: 0.6rem 0;
    min-height: 44px;
    font-size: 1.04rem;
  }
  .crumbs a { min-width: 44px; text-align: left; }
}

/* ---------- mobile pass, round four: the last components ---------- */

/* The eyebrow on --paper-2 sat at 4.21:1, same near-miss as the links there. */
.section-alt:not(.section-dark) .eyebrow,
.section-alt:not(.section-dark) .sec-head .eyebrow,
.section-alt:not(.section-dark) .stamp { color: var(--copper-ink); }

/* Diagnosis tags on the symptom cards measured 4.46:1, a hair under. */
.tag { color: var(--copper-ink); }


@media (max-width: 720px) {
  /* ZIP chips: 13.1px text in a 45x36 target. These are a primary navigation
     affordance on the city pages, so they get real size. */
  .zip-chip {
    font-size: 0.96rem;
    min-height: 44px;
    min-width: 62px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.55rem 0.8rem;
  }
  /* Symptom card tags were the smallest text left on the site at 10.9px. */
  .tag { font-size: 0.94rem; line-height: 1.5; }
  .guide-more, .guide-kicker { font-size: 0.96rem; }
  /* Standalone links that sit alone in their own paragraph are navigation, not
     prose, so they get a real touch target. */
  .section > .wrap > p > a:only-child,
  .section-alt > .wrap > p > a:only-child,
  .section-dark > .wrap > p > a:only-child {
    display: inline-block;
    padding: 0.6rem 0;
    min-height: 44px;
    font-size: 1.04rem;
  }
}

/* ---------- mobile pass, round five: homepage components ----------
   Stamps measured 4.46:1 rather than the ~5:1 I calculated for copper-deep on
   paper, so light surfaces get copper-ink across the board rather than my
   arithmetic. The area index heading was the worst thing left on the site at
   10.9px and 2.6:1. */
.section:not(.section-dark) .stamp,
.section-alt:not(.section-dark) .stamp { color: var(--copper-ink); }
.trust-chips li { color: var(--copper-ink); }

.area-head { color: var(--copper-ink); }


@media (max-width: 720px) {
  .area-head { font-size: 0.98rem; letter-spacing: 0.14em; }
  .trust-chips li { font-size: 1rem; line-height: 1.6; }
  .badge-pill { font-size: 0.96rem; }
  .area-zips { font-size: 0.95rem; }
  .guide-more, .guide-kicker { font-size: 0.98rem; }
}

/* Stacked diagram labels: viewBox units on a 340-wide box render close to 1:1
   on a phone, so these numbers are effectively px. */
.dg-tall .dg-rel { font-size: 15px; }
.dg-tall .dg-note { font-size: 15.5px; }
.dg-tall .dg-name { font-size: 18px; }

/* Last two near-misses on the homepage. */
@media (max-width: 720px) {
  .wrap ul.trust-chips li { font-size: 1.08rem; }
  .guides-grid a.guide-card span.guide-more { font-size: 1rem; }
}

/* =========================================================================
   MOBILE HERO ARTWORK 2026-08-13
   The gauge manifold is hidden under 820px because it is too wide to read on a
   phone, which left the mobile hero as a flat dark rectangle: legible, but with
   none of the character the desktop hero has. Since most of the traffic here is
   a homeowner on a phone, that was the wrong half to lose.

   Mobile keeps the fan, which reads fine at small sizes, plus the blueprint
   grid, and gains a single gauge face bottom-left as a nod to the manifold.
   ========================================================================= */
@media (max-width: 820px) {
  .hero-mid::before {
    display: block;
    top: 40%;
    right: -34%;
    width: min(118vw, 560px);
    height: min(118vw, 560px);
    opacity: 0.17;
  }
  .hero:not(.hero-mid)::before {
    display: block;
    top: 50%;
    right: -42%;
    width: min(92vw, 420px);
    height: min(92vw, 420px);
    opacity: 0.10;
  }
  /* Breathing room the desktop layout got from its wider measure. */
  .hero h1 { margin-bottom: 1.2rem; }
  .hero-deck { margin-bottom: 0.9rem; }
  .hero-mid .hero-ctas { margin-top: 2rem; }

  /* "Or send the details" was a cramped underlined string. It is the secondary
     action on the most important screen, so it gets a real target. */
  .hero-alt-cta {
    display: inline-block;
    min-height: 44px;
    padding: 0.7rem 0;
    font-size: 1.02rem;
    letter-spacing: 0.04em;
    opacity: 0.92;
  }
}

/* =========================================================================
   MOBILE HERO ARTWORK, CORRECTED 2026-08-13
   Jay's call: on phones the manifold gauges are the background, not the fan.
   The fan is a wide circular form, so at 390px it crops into an unreadable
   blade shape. The gauge manifold is 300x540, portrait, which is the right
   proportion for a phone screen.
   ========================================================================= */
@media (max-width: 820px) {
  /* Fan off on every hero at phone width. */
  .hero-mid::before,
  .hero:not(.hero-mid)::before { display: none; }

  /* Manifold on, anchored to the bottom-right so the linework runs off the
     edge deliberately instead of floating, and the copy column stays clear. */
  .hero .hero-gauges,
  .hero-mid .hero-gauges,
  .hero:not(.hero-mid) .hero-gauges {
    display: block;
    top: auto;
    bottom: 0;
    left: auto;
    right: -16%;
    height: min(74%, 620px);
    width: auto;
    opacity: 0.26;
  }
  .hero:not(.hero-mid) .hero-gauges { height: min(78%, 380px); opacity: 0.20; }
}

@media (max-width: 430px) {
  .hero .hero-gauges { right: -26%; height: min(66%, 540px); opacity: 0.24; }
}

/* =========================================================================
   MOBILE HERO GAUGES, SIZED PROPERLY 2026-08-13
   Previous attempt was too small and pushed 26% off the right edge, so it read
   as a cropped fragment floating in the lower right rather than artwork.

   The manifold viewBox is 300x540. The gauge faces sit at y=150 (upper third)
   and three hoses run from the manifold at y=305 down to y=540, the very bottom
   of the viewBox. So anchoring bottom:0 at close to full hero height is what
   makes the hoses run to the end of the section, which is the intent.
   ========================================================================= */
@media (max-width: 820px) {
  .hero .hero-gauges,
  .hero-mid .hero-gauges,
  .hero:not(.hero-mid) .hero-gauges {
    display: block;
    top: auto;
    bottom: 0;
    left: auto;
    right: -14%;
    height: 90%;
    width: auto;
    opacity: 0.30;
  }
  /* Interior heroes are much shorter, so the same percentage would shrink the
     artwork to nothing. It gets a floor and sits a touch quieter. */
  .hero:not(.hero-mid) .hero-gauges {
    height: max(90%, 300px);
    right: -22%;
    opacity: 0.22;
  }
}

@media (max-width: 430px) {
  .hero .hero-gauges, .hero-mid .hero-gauges { right: -18%; height: 88%; opacity: 0.30; }
  .hero:not(.hero-mid) .hero-gauges { right: -26%; opacity: 0.22; }
}

/* Weighted to the right half.
   At 90% height the 300x540 artwork computes to 387px wide on a 390px screen,
   which is effectively full-bleed and reads as centred rather than as a right-
   side background. Reducing the height narrows it proportionally, so both gauge
   faces stay on screen while the whole assembly sits right of the text column.
   bottom:0 is retained, which is what keeps the hoses on the section floor. */
@media (max-width: 820px) {
  .hero .hero-gauges, .hero-mid .hero-gauges {
    height: 72%;
    right: -6%;
    opacity: 0.27;
  }
}
@media (max-width: 430px) {
  .hero .hero-gauges, .hero-mid .hero-gauges {
    height: 70%;
    right: -7%;
    opacity: 0.27;
  }
}

/* Interior heroes get the same right-weighted treatment as the homepage. They
   are shorter, so a percentage height alone made the artwork proportionally
   huge relative to the copy. */
@media (max-width: 820px) {
  .hero:not(.hero-mid) .hero-gauges {
    height: 70%;
    right: -8%;
    opacity: 0.22;
  }
}
@media (max-width: 430px) {
  .hero:not(.hero-mid) .hero-gauges { height: 68%; right: -9%; opacity: 0.22; }
}

/* =========================================================================
   MOBILE HERO GAUGES, LAID OUT TO JAY'S SKETCH 2026-08-13
   Three corrections from the drawing:
     1. the assembly sits HIGHER, gauge faces level with the headline stack
        rather than down beside the body copy
     2. it is BIGGER and pushed further right, so the right gauge clips on the
        screen edge instead of the whole thing floating inside the column
     3. the hoses OVERRUN the section floor instead of stopping on it, which is
        what makes it read as artwork continuing past the frame

   Geometry, against a 792px hero and the 300x540 viewBox:
     height 105% -> 462px wide, left edge x=67
     left gauge x=182, right gauge x=413 so it clips at the 390px edge
     gauge faces land 34% down the hero, level with the headline
     hoses run to 79px below the hero floor and are clipped by overflow:hidden
   ========================================================================= */
@media (max-width: 820px) {
  .hero .hero-gauges,
  .hero-mid .hero-gauges {
    height: 105%;
    bottom: -10%;
    right: -30%;
    opacity: 0.28;
  }
  .hero:not(.hero-mid) .hero-gauges {
    height: 104%;
    bottom: -12%;
    right: -34%;
    opacity: 0.20;
  }
}
@media (max-width: 430px) {
  .hero .hero-gauges, .hero-mid .hero-gauges {
    height: 104%; bottom: -10%; right: -34%; opacity: 0.28;
  }
  .hero:not(.hero-mid) .hero-gauges {
    height: 102%; bottom: -12%; right: -38%; opacity: 0.20;
  }
}

/* =========================================================================
   MOBILE HERO GAUGES, TOP-RIGHT 2026-08-13
   Jay's correction: smaller, hugging the right edge, starting just below the
   badge pill so it occupies the empty space beside the headline stack rather
   than sprawling across the whole hero from the floor up.

   Top-anchored now, not bottom. Against a 792px hero and the 300x540 viewBox:
     height 56% -> 246px wide, top 87px which clears the badge
     left edge x=158 so the headline column stays clear
     right edge x=405 so it hugs and just kisses the 390px screen edge
     gauge faces land 211px down, level with HEATING and COOLING
   ========================================================================= */
@media (max-width: 820px) {
  .hero .hero-gauges,
  .hero-mid .hero-gauges {
    top: 11%;
    bottom: auto;
    right: -6%;
    left: auto;
    height: 56%;
    opacity: 0.30;
  }
  .hero:not(.hero-mid) .hero-gauges {
    top: 14%;
    bottom: auto;
    right: -8%;
    height: 60%;
    opacity: 0.22;
  }
}
@media (max-width: 430px) {
  .hero .hero-gauges, .hero-mid .hero-gauges {
    top: 11%; right: -8%; height: 54%; opacity: 0.30;
  }
  .hero:not(.hero-mid) .hero-gauges {
    top: 14%; right: -10%; height: 58%; opacity: 0.22;
  }
}

/* The hoses now terminate mid-hero rather than running off the floor, so their
   flat cut ends were visible and read as unfinished. A soft mask dissolves the
   bottom of the artwork instead, which is what makes a compact top-right
   placement look deliberate. */
@media (max-width: 820px) {
  .hero .hero-gauges {
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 62%, transparent 97%);
    mask-image: linear-gradient(to bottom, #000 0%, #000 62%, transparent 97%);
  }
}

/* =========================================================================
   MOBILE HERO GAUGES, FINAL PLACEMENT 2026-08-13
   Jay: higher, a touch bigger, hoses running to the complete end of the section.

   Solved rather than nudged. The gauge circles occupy y=95..205 of the 540
   viewBox, so the gauge TOP is 17.6% into the artwork. Two constraints:
     gauge faces begin just under the badge pill, which ends around 83px
     the hoses finish exactly on the hero floor
   Solving both against a 792px hero gives height 107%, top -7%.
   That is 471px wide, so right:-23% lets the right gauge clip the screen edge
   while the left gauge and the full hose run stay on screen.

   The fade mask is removed: it existed only because the hoses used to stop
   mid-hero, and they now reach the floor as intended.
   ========================================================================= */
@media (max-width: 820px) {
  .hero .hero-gauges,
  .hero-mid .hero-gauges {
    top: -7%;
    bottom: auto;
    right: -23%;
    left: auto;
    height: 107%;
    opacity: 0.28;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .hero:not(.hero-mid) .hero-gauges {
    top: -6%;
    bottom: auto;
    right: -28%;
    height: 106%;
    opacity: 0.20;
    -webkit-mask-image: none;
    mask-image: none;
  }
}
@media (max-width: 430px) {
  .hero .hero-gauges, .hero-mid .hero-gauges { top: -7%; right: -27%; height: 107%; }
  .hero:not(.hero-mid) .hero-gauges { top: -6%; right: -32%; height: 106%; }
}

/* =========================================================================
   MOBILE HERO GAUGES, SIZED TO THE SKETCH 2026-08-13
   Jay: gauges too big. Measured off his drawing, he wants roughly an 85px
   gauge face, but with the hoses running about three times longer relative to
   the gauges than the artwork actually draws them.

   Scaling the whole SVG cannot do both: shrink it for small gauges and the
   hoses stop a third of the way down. So the hose group is stretched on its
   own, anchored at the manifold outlet (viewBox 150,305). The svg already
   carries overflow:visible, so the extended ends render past the viewBox.

   Solved against a 792px hero:
     height 53%  -> 233px wide, gauge faces about 86px across
     top 2.6%    -> gauge faces begin 94px down, just under the badge pill
     right -18%  -> left gauge x=257, right gauge x=374, hugging the edge
     scaleY(2.93) on the hoses lands them exactly on the section floor
   ========================================================================= */
@media (max-width: 820px) {
  .hero .hero-gauges,
  .hero-mid .hero-gauges,
  .hero:not(.hero-mid) .hero-gauges {
    top: 2.6%;
    bottom: auto;
    left: auto;
    right: -18%;
    height: 53%;
    opacity: 0.30;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .hero:not(.hero-mid) .hero-gauges { top: 4%; height: 50%; opacity: 0.22; }

  .hero-gauges .gz-hoses {
    transform-box: view-box;
    transform-origin: 150px 305px;
    transform: scaleY(2.93);
  }
  .hero:not(.hero-mid) .hero-gauges .gz-hoses { transform: scaleY(2.2); }
}
@media (max-width: 430px) {
  .hero .hero-gauges, .hero-mid .hero-gauges { right: -20%; height: 52%; }
  .hero:not(.hero-mid) .hero-gauges { right: -22%; height: 49%; }
}

/* The third hose sat just past the right edge at -18%. Pulling it back so all
   three show, which is what the sketch has. */
@media (max-width: 820px) {
  .hero .hero-gauges, .hero-mid .hero-gauges { right: -9%; }
  .hero:not(.hero-mid) .hero-gauges { right: -12%; }
}
@media (max-width: 430px) {
  .hero .hero-gauges, .hero-mid .hero-gauges { right: -11%; }
  .hero:not(.hero-mid) .hero-gauges { right: -14%; }
}

/* =========================================================================
   MOBILE HERO GAUGES, FINAL 2026-08-13
   Jay: shift left so the gauges nearly meet the headline, fit BOTH gauges on
   screen, and make it a touch bigger.

   right:0 pins the artwork's right edge to the screen edge, which is what puts
   the second gauge fully in frame instead of clipping it. Height 55% then sets
   the width at 242px, so:
     left gauge  x=164 to 253   (headline runs to about 203 at that height)
     right gauge x=285 to 374   fully on screen
     gauge faces 90px across, beginning 96px down, just under the badge
   scaleY on the hoses drops to 2.78 because the taller artwork already covers
   more of the drop to the floor.
   ========================================================================= */
@media (max-width: 820px) {
  .hero .hero-gauges,
  .hero-mid .hero-gauges,
  .hero:not(.hero-mid) .hero-gauges {
    top: 2.4%;
    bottom: auto;
    left: auto;
    right: 0;
    height: 55%;
    opacity: 0.30;
  }
  .hero:not(.hero-mid) .hero-gauges { top: 4%; height: 52%; opacity: 0.22; }
  .hero-gauges .gz-hoses { transform: scaleY(2.78); }
  .hero:not(.hero-mid) .hero-gauges .gz-hoses { transform: scaleY(2.1); }
}
@media (max-width: 430px) {
  .hero .hero-gauges, .hero-mid .hero-gauges { right: 0; height: 54%; }
  .hero:not(.hero-mid) .hero-gauges { right: 0; height: 51%; }
}

/* =========================================================================
   MOBILE HERO ARTWORK, RESTRAINED 2026-08-13
   Reset after eight rounds of nudging that were not converging. The mistake was
   architectural, not numeric: a manifold with three long hoses is a busy
   foreground object, and stretching it down a 390px screen at 30% opacity read
   as clutter crossing every paragraph, not as a background.

   The hoses are dropped on mobile. What is left is the part that reads
   instantly at a glance, the twin gauge heads and the manifold body, held as a
   compact accent in the top-right corner where the hero is genuinely empty.
   Desktop is untouched and keeps the full composition.
   ========================================================================= */
@media (max-width: 820px) {
  .hero-gauges .gz-hoses { display: none; }

  .hero .hero-gauges,
  .hero-mid .hero-gauges,
  .hero:not(.hero-mid) .hero-gauges {
    top: 3%;
    bottom: auto;
    left: auto;
    right: -7%;
    height: 46%;
    opacity: 0.26;
  }
  .hero:not(.hero-mid) .hero-gauges { top: 5%; height: 42%; opacity: 0.20; }
}
@media (max-width: 430px) {
  .hero .hero-gauges, .hero-mid .hero-gauges { right: -9%; height: 44%; }
  .hero:not(.hero-mid) .hero-gauges { right: -11%; height: 40%; }
}

/* Nothing may hang off the right edge. A negative right offset chopped the
   second gauge in half, which reads as a rendering fault rather than a crop.
   right:0 keeps the whole assembly on screen. */
@media (max-width: 820px) {
  .hero .hero-gauges,
  .hero-mid .hero-gauges,
  .hero:not(.hero-mid) .hero-gauges {
    right: 0;
    height: 44%;
  }
  .hero:not(.hero-mid) .hero-gauges { height: 40%; }
}
@media (max-width: 430px) {
  .hero .hero-gauges, .hero-mid .hero-gauges { right: 0; height: 42%; }
  .hero:not(.hero-mid) .hero-gauges { right: 0; height: 38%; }
}

/* =========================================================================
   MOBILE HERO GAUGES 2026-08-13, final composition
   Jay: lower the gauges, bring the hoses back straight or semi-straight, make
   it look professional.

   Hoses restored on mobile with the shallow original sway. Under scaleY(3.48)
   that 28px of horizontal drift spreads over a 528px run, a 1:19 ratio, so they
   read as long near-straight hoses with a slight lean rather than the wandering
   lines of the previous attempt. Nothing crosses the right edge.

   height 44%, top 8.5%, right 0 -> 194px wide, sitting x=196 to 390
   gauge faces 72px across, beginning 129px down the hero
   ========================================================================= */
@media (max-width: 820px) {
  .hero-gauges .gz-hoses { display: block; }

  .hero .hero-gauges,
  .hero-mid .hero-gauges,
  .hero:not(.hero-mid) .hero-gauges {
    top: 8.5%;
    bottom: auto;
    left: auto;
    right: 0;
    height: 44%;
    opacity: 0.26;
  }
  .hero-gauges .gz-hoses {
    transform-box: view-box;
    transform-origin: 150px 305px;
    transform: scaleY(3.48);
  }
  .hero:not(.hero-mid) .hero-gauges { top: 9%; height: 40%; opacity: 0.19; }
  .hero:not(.hero-mid) .hero-gauges .gz-hoses { transform: scaleY(2.6); }
}
@media (max-width: 430px) {
  .hero .hero-gauges, .hero-mid .hero-gauges { height: 42%; }
  .hero:not(.hero-mid) .hero-gauges { height: 38%; }
}

/* Hours line under the contact hero. */
.hours-line {
  font-family: var(--font-plate);
  font-size: 0.92rem;
  letter-spacing: 0.06em;
  color: var(--on-dark-muted);
  margin: 0 0 1.2rem;
}

/* ---------------------------------------------------------------------------
   Guide cards: make them read as cards
   Jay 2026-08-13, on a mobile screenshot: "can you fix so it doesn't blend in
   like it does". He was right, and there were three separate causes:

   1. The fill was rgba(255,255,255,0.02) over a dark blueprint gradient. That
      is roughly a 1% lift, invisible on a phone in daylight. The card had no
      surface, only an outline.
   2. The border was --steel-line (#39434f) against a ground of nearly the same
      value, so the outline barely resolved either.
   3. Every card except the feature hid its blurb, and .guide-more used
      margin-top:auto inside equal-height grid rows. On mobile the grid drops to
      one column, so each card became a title, a large dead gap, and a grey
      "Read it". Hollow boxes.

   The fix gives them a genuine raised surface, an edge that resolves, a copper
   marker so the eye catches the card before the text, and real content on
   mobile instead of a void.
   --------------------------------------------------------------------------- */
.guide-card {
  position: relative;
  /* OPAQUE, not a white wash. The first attempt used translucent white, which
     let the blueprint grid of the section run straight through the card. A
     surface you can see the floor through does not read as a surface, which is
     exactly the "blends in" Jay was pointing at. This paints its own panel, a
     step lighter than --steel (#222b35), so the card sits ON the section
     instead of inside it. */
  background: linear-gradient(158deg, #2b3541 0%, #242d38 58%, #1f2731 100%);
  border: 1px solid rgba(214, 226, 240, 0.22);
  border-radius: 4px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.055) inset,
              0 10px 26px -18px rgba(0, 0, 0, 0.85);
  overflow: hidden;
}
/* A short copper rule on the top edge. The eye lands on it before it reads a
   word, which is what separates a card from a rectangle. */
.guide-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3.25rem;
  height: 3px;
  background: var(--copper);
}
.guide-feature::before { width: 5.5rem; }
.guide-card:hover, .guide-card:focus-visible {
  background: linear-gradient(158deg, #3a3129 0%, #2d3038 60%, #242d38 100%);
  border-color: var(--copper);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.09) inset,
              0 16px 30px -18px rgba(0, 0, 0, 0.9);
}
.guide-card:hover::before, .guide-card:focus-visible::before { width: 100%; }
.guide-card::before { transition: width var(--duration) var(--ease); }

/* "Read it" was --on-dark-muted grey and read as disabled text rather than the
   thing you tap. It is now the copper affordance it should always have been,
   with an arrow that moves on hover. */
/* Two classes, because line 1072's `.section-dark .guide-more` also has two and
   a bare `.guide-more` here loses the cascade to it. */
.guide-card .guide-more {
  color: var(--copper);
  font-weight: 700;
  letter-spacing: 0.08em;
}
.guide-more::after {
  content: "\2192";
  display: inline-block;
  margin-left: 0.45rem;
  transition: transform var(--duration) var(--ease);
}
.guide-card:hover .guide-more::after,
.guide-card:focus-visible .guide-more::after { transform: translateX(4px); }
/* --copper (#c97a3a) measures 3.75:1 on the card's lightest gradient stop,
   under the 4.5:1 floor for the small "Guide" label. #db9457 measures 4.97:1
   against that same worst-case stop. The marker rule and the "Read it" link are
   large/bold enough to pass at --copper, so only this label changes. */
.guide-card .guide-kicker { color: #db9457; }

/* Below the 2-column break the cards stack, so there is room for the blurb and
   no reason to leave a hollow box. Dropping margin-top:auto also removes the
   stretched gap that equal-height rows were creating. */
@media (max-width: 860px) {
  .guide-card:not(.guide-feature) .guide-blurb { display: block; }
  .guide-blurb { max-width: none; }
  .guide-more { margin-top: 0.25rem; padding-top: 0.55rem; }
  .guide-card { gap: 0.45rem; }
}

/* Measured 14.7px, under the floor for readers in glasses. The audit classes a
   <p> in the hero as body text, so it needs the 17px body floor, not the 15px
   secondary one. rem is root-relative, which is why an earlier "fix" of the same
   kind landed short. */
.hero .hours-line { font-size: 1.0625rem; }

/* ---------------------------------------------------------------------------
   Hero fixes, Jay 2026-08-13
   --------------------------------------------------------------------------- */

/* 1. THE FAN WAS TOUCHING THE HEADLINE.
   Measured with Range.getBoundingClientRect() on the actual glyphs, not the
   span boxes, which are full column width and say nothing about where the
   letters stop. The widest line is "Air Quality.", not "Done Right.", and the
   overlap got worse as the window narrowed:
       1280 wide  overlapped 111px
       1512 wide  overlapped  61px
       1920 wide  cleared by  55px
   Solved across ten viewports from 1180x800 to 2560x1440 rather than tuned at
   one width. Two fixes clear the text: push the fan further off the right edge,
   or shrink it. Pushing it clears the type by HIDING the fan, dropping the
   on-screen portion to roughly 40%. Shrinking to 70vh clears every viewport by
   at least 30px while keeping 66 to 73% of the circle visible, which is what it
   shows today. So: shrink, do not push. */
.hero::before {
  width: min(70vh, 1000px);
  height: min(70vh, 1000px);
}

/* 2. MANIFOLD GAUGES SIT TOO LOW.
   Lift and scale, per Jay. The artwork is anchored bottom:0, so growing its
   height lifts the dials while the hoses still reach the bottom edge of the
   section. Height 105% is the ceiling here: the hook curl starts at y=28 in a
   540-unit viewBox, and above about 105% the top of the curl crosses the hero's
   overflow:hidden edge and gets sliced. The px cap rises in the same proportion
   (1060 * 105/92) so very tall viewports lift by the same amount instead of
   pinning to the old cap.

   Scoped to min-width 821px on purpose. Every mobile rule for this artwork
   lives in a max-width query and was approved after a long round of revisions,
   so a desktop-only query cannot reach it. */
@media (min-width: 821px) {
  .hero-mid .hero-gauges { height: min(105%, 1210px); }
}

/* 3. WORDMARK GOES ALL WHITE.
   Copper meant "Cooling" in the hero and "Heating" in the logo, two different
   jobs for one colour on the same screen. The copper mark now carries the
   colour on its own, which also matches the copper-only badge that goes on
   trucks, shirts and invoices. */
.brand-name .mha-copper,
.footer-brand .mha-copper { color: inherit; }

/* ---------------------------------------------------------------------------
   Hero: centre the copy in the channel between the two artworks.
   Jay 2026-08-13: "All the words have to be centered perfectly between the
   gauges and the fan" and the fan had been shrunk too far.

   ROOT CAUSE of the drifting gaps. The copy lives in .hero-inner, which sits
   inside a CENTRED 1180px .wrap. Both artworks were pinned to the VIEWPORT
   edges (.hero-gauges left:-3%, .hero::before right:-13%). Those two anchors do
   not move together, so as the window widens the copy slides right while the
   artwork stays put, and the left and right gaps swing apart. No choice of flat
   percentages can fix that, which is why the first attempt only balanced at one
   width.

   FIX: anchor both artworks to the wrap instead of the viewport, so all three
   move as one. With
       gauge right edge = wrapLeft + (off - G)
       fan left edge    = wrapLeft + off + textWidth + G
   the two gaps both reduce to G at every width.

   `off` is the copy's offset inside the wrap. It is not constant: measured at
   234px at 1180 wide, rising to a 290px ceiling from 1920 up. Flat constants
   left a 66px swing. clamp(234px, 108px + 10vw, 290px) fits the measured curve
   within about 6px and cuts the worst asymmetry to 15px, and to 6px or less
   across the widths most people actually use.

   textWidth is 526px, the width of "Air Quality.", the longest of the four
   headline lines. It is stable from 1280 up because the headline size clamps.

   Verified at ten viewports from 1180x800 to 2560x1440: smallest gap 54px,
   nothing touching anywhere. Fan returns to its original min(86vh, 1000px).
   Desktop only, since every mobile rule for this artwork lives in a max-width
   query and was approved separately.
   --------------------------------------------------------------------------- */
@media (min-width: 821px) {
  .hero-mid .hero-gauges {
    left: auto;
    right: calc(100% - max(0px, 50% - 590px)
                - (clamp(234px, 108px + 10vw, 290px) - 60px));
  }
  .hero-mid::before {
    right: auto;
    left: calc(max(0px, 50% - 590px)
               + clamp(234px, 108px + 10vw, 290px) + 526px + 60px);
    width: min(86vh, 1000px);
    height: min(86vh, 1000px);
  }
}

/* Anchoring the gauges by `right` with `left:auto` made the box shrink-to-fit.
   Shrink-to-fit caps the width at the space available from the container's left
   edge, and the global `img, svg { max-width: 100% }` reset then squeezed the
   svg inside it. preserveAspectRatio letterboxed the artwork, so the gauges
   rendered about 30% smaller and floated vertically instead of sitting on the
   bottom edge, which stopped the hoses reaching the bottom of the section.

   Giving the box an explicit aspect ratio derives its width from its height
   instead of from the available space, so the artwork keeps its full size and
   bleeds off the left edge the way it did before. 5/9 is the artwork's own
   300 x 540 viewBox. */
@media (min-width: 821px) {
  .hero-mid .hero-gauges { aspect-ratio: 5 / 9; width: auto; }
  .hero-mid .hero-gauges svg { max-width: none; }
}

/* Footer column headings moved from h3 to h2 so pages whose main content has no
   h2 (thanks.html) no longer jump h1 -> h3, which breaks the outline a screen
   reader announces. The old rule only matched h3, so without this the footer
   headings would inherit the global h2 size and blow the footer apart. */
.site-footer h2 {
  color: var(--copper);
  font-size: 1.15rem;
  letter-spacing: 0.08em;
  line-height: 1.2;
}

/* ===========================================================================
   TYPE FLOOR SWEEP, 2026-08-14
   Found by rendering all 288 pages at 1512x950 and 390x844 and measuring the
   computed font-size of every text node, rather than spot-checking 13 pages.

   Nothing on a page a homeowner reads should render below 12px. The site had
   9.6px on all 288 pages (.brand-geo) and on 273 (.proof-k), plus a run of
   10.6 to 11.8px labels. Uppercase and letterspaced makes small type worse to
   read, not better, and the audience here includes people wearing glasses.

   Values are stated in rem against the 16px root: 0.75rem = 12px.
   Desktop-scoped, because the mobile sizes for these classes live in
   max-width queries that were tuned separately and already clear their floor.
   Selectors mirror the originals so specificity matches and order decides.
   =========================================================================== */
/* Was min-width:821px, which left 561 to 820px falling through to the base
   sizes. The 11-viewport sweep found .brand-geo at 9.6px on every page across
   that whole range. 721px is the right floor here because the mobile rules for
   these classes live in max-width:720 queries and already set LARGER sizes;
   starting at 481 would have overridden them downward to 12px. */
@media (min-width: 721px) {
  .brand-geo               { font-size: 0.75rem; }   /* was 0.60rem,  9.6px */
  .proof-k                 { font-size: 0.75rem; }   /* was 0.60rem,  9.6px */
  .guide-kicker, .area-sub { font-size: 0.75rem; }   /* was 0.66rem, 10.6px */
  .tag                     { font-size: 0.75rem; }   /* was 0.68rem, 10.9px */
  .area-zips               { font-size: 0.75rem; }   /* was 0.70rem, 11.2px */
  .stamp                   { font-size: 0.75rem; }   /* was 0.74rem, 11.8px */
  .sec-head .eyebrow       { font-size: 0.75rem; }   /* was 0.74rem, 11.8px */

  /* A link needs to look tappable, so it gets more than the bare floor. */
  .guide-more              { font-size: 0.8125rem; } /* was 0.70rem, 11.2px */

  /* .area-head is an <h3>. A heading rendering at 10.9px, smaller than the body
     text beneath it, inverts the hierarchy it exists to create. */
  .area-head               { font-size: 0.875rem; }  /* was 0.68rem, 10.9px */
}

/* Two phone sizes raised on merit rather than to satisfy a floor.
   .header-call is the phone number in the header and the primary way this
   business gets work, so it should not be the smallest thing in the bar.
   .proof-v is a readable sentence, not a label, so it belongs at body size. */
@media (max-width: 480px) {
  .header-call { font-size: 1.0625rem; }             /* was 0.95rem, 15.2px */
}
@media (max-width: 720px) {
  .proof-v { font-size: 1.0625rem; }                 /* was 1.02rem, 16.3px */
}

/* Last three type findings from the 288-page render sweep, all on the homepage.

   .trust-chips li are uppercase letterspaced chips, but one of them is a full
   sentence ("The person who quotes it is the person who tested it"). A sentence
   set in a mono face, uppercase and letterspaced at 12.5px is genuinely hard
   work. Raised to 14px.

   .guide-blurb is a real paragraph on a card, sitting just under the 15px prose
   floor at 14.7px.

   The diagram caption carries the domino explanation, which is the single most
   important idea on the site, and it was the smallest prose on the phone. */
.trust-chips li { font-size: 0.875rem; }             /* was 0.78rem, 12.5px */
.guide-blurb    { font-size: 0.9375rem; }            /* was 0.92rem, 14.7px */
@media (max-width: 820px) {
  .diagram figcaption { font-size: 1.0625rem; }      /* was 15.2px on phone */
}

/* Guide-card blurbs are shown on phones (they were hidden before, which left
   hollow cards). They are real paragraphs, so they take the 17px body floor
   rather than the 15px they inherited from the desktop card size. */
@media (max-width: 860px) {
  .guide-blurb { font-size: 1.0625rem; line-height: 1.55; }
}

/* ZIP index on the service-area page. Every ZIP page used to be reachable only
   from an individual service-city page, which left two of them four clicks from
   the homepage. Crawl depth is a ranking input and four is too deep for a page
   meant to catch "hvac 21701" searches. */
.zip-index {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin-top: 1.2rem;
}

/* ZIP chips inside a dark section.

   Caused by my own change earlier today: `.section-dark .zip-chip` matched
   nothing at the time, so the dead-CSS sweep removed it. Then the new ZIP index
   went into a dark section, and with no dark-context rule the chips fell through
   to `background: var(--card)` (light) while the generic dark-section link rule
   painted the text copper. Copper on white measures 3.32:1, under the 4.5 floor.
   Caught by the 288-page render audit, not by eye. */
.section-dark .zip-chip {
  color: var(--on-dark);
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(214, 226, 240, 0.22);
}
.section-dark .zip-chip:hover {
  color: var(--ink);
  background: var(--copper);
  border-color: var(--copper);
}

/* Replacements for two style= attributes, removed so the Content-Security-Policy
   does not need 'unsafe-inline' on styles for them. */
.mt-0 { margin-top: 0; }
.jc-center { justify-content: center; }
.ghl-iframe { width: 100%; height: 640px; border: none; border-radius: 4px; }

/* .area-row matched :focus-visible but its only focus treatment was widening a
   ::before marker and changing colour, so keyboard users got no ring at all.
   Found by tabbing the live page rather than by calling el.focus(), which does
   not reliably trigger :focus-visible and had reported a false pass.
   WCAG 2.4.7 needs a visible indicator, so this restores the site-wide one. */
.area-row:focus-visible {
  outline: 3px solid var(--copper);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------------------------------------------------------------------------
   MOBILE HEADER FIX, 2026-08-14.
   Jay: "massive differences in mobile this time around". Measured across five
   phone widths and he is right. The wordmark was wrapping to THREE lines at
   320, 360 and 390px, squeezed into 56 to 94px of space, which made the header
   76px tall and looked broken.

   Cause was mine: the type-floor sweep raised .header-call from 0.95rem to
   1.0625rem, taking that button to 123px and leaving the brand nothing.

   Fix: on phones the header call button becomes an icon-only 44px tap target.
   The number is not lost, it appears three other places on the same screen:
   the hero, the sticky CALL NOW bar that sits on every page, and the footer.
   Trading a fourth copy of the number for a wordmark that does not break is
   the right call.
   --------------------------------------------------------------------------- */
.hc-icon { display: none; }
.hc-num { display: inline; }

@media (max-width: 560px) {
  .header-call {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 48px;
    min-height: 44px;
    padding: 0 0.7rem;
  }
  .hc-icon { display: block; width: 22px; height: 22px; }
  .hc-num  { display: none; }

  /* A designed two-line lockup rather than an accidental three-line one. */
  .brand-name { font-size: 1.02rem; line-height: 1.12; letter-spacing: 0.03em; }
  .site-header .brand { gap: 0.55rem; }
}

/* ---------------------------------------------------------------------------
   HORIZONTAL OVERFLOW IN THE SERVICE-AREA INDEX, 2026-08-14.

   The page scrolled sideways from 561 to 700px and again at 980px. Cause:
   .area-zips carried white-space:nowrap, so a city with five ZIP codes
   ("20901 20902 20903 20904 20906") had a minimum width no flex or column
   layout could honour. Inside column-count:2 that pushed the whole grid past
   the viewport.

   This had been live and invisible because the render audit only ever tested
   390px and 1512px. Both of those happen to be widths where it does not
   trigger. The audit now sweeps eleven widths.

   ZIPs are space separated, so normal wrapping breaks between codes and never
   inside one. min-width:0 lets the flex children actually shrink, which they
   cannot do by default.
   --------------------------------------------------------------------------- */
.area-zips { white-space: normal; min-width: 0; }
.area-name { min-width: 0; }
.area-row  { flex-wrap: wrap; }

/* ---------------------------------------------------------------------------
   320px HEADLINE OVERFLOW, 2026-08-14.
   On a 320px screen the hero h1 rendered at 53.6px, which makes the single word
   "Gaithersburg," 302px wide on its own. A word cannot be broken, so it forced
   the wrap to 334px, 14px past the screen edge. Long city names are the whole
   point of these pages, so the type has to yield, not the name.
   --------------------------------------------------------------------------- */
@media (max-width: 360px) {
  /* .hero-lines only exists on the homepage. City and service pages carry a
     bare <h1> inside .hero, which is exactly where the long town names live, so
     the selector has to be .hero h1 to reach them. */
  .hero h1, .hero-lines { font-size: clamp(1.9rem, 11vw, 2.6rem); line-height: 1.04; }
  .hero h1 { overflow-wrap: break-word; }
}

/* .brand-geo is hidden below 481px already. Extending that to 720px rather than
   sizing it up: at the 15px a label needs to be legible on a touch device, the
   service-area string is about 380px wide, which will not
   share a 560px header with the mark, MENU and the call button. The same
   information is in the hero badge, the footer and the schema on every page, so
   nothing is lost by dropping it from the small-tablet header. */
@media (max-width: 720px) {
  .brand-geo { display: none; }
}

/* ===========================================================================
   STICKY CTA BAR, REBUILT 2026-08-14.

   Jay on an iPhone 17 Pro Max: "they kind of blend in, right? navy blue, navy
   blue, and then there's the gold orange below it." He is right. Two of the
   three buttons were flat --ink, the same colour as the page behind them,
   separated only by a 1px hairline. Only one of the three read as a button.

   Now each is a real, distinct control with its own fill, its own border and an
   icon, sitting on a deeper bar that lifts off the page with a shadow:
     Call Now     solid copper, dark text        primary
     Text Us      steel fill, light border       secondary
     Book Online  outlined in copper             tertiary
   Icons are inline SVG so they cost no request and inherit currentColor.
   =========================================================================== */
.sticky-cta {
  background: #090c10;
  border-top: 2px solid var(--copper);
  box-shadow: 0 -8px 22px -10px rgba(0, 0, 0, 0.85);
  padding: 7px;
  gap: 7px;
  padding-bottom: calc(7px + env(safe-area-inset-bottom, 0px));
}
.sticky-cta .scta {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.42rem;
  min-height: 50px;
  padding: 0.5rem 0.25rem;
  border-radius: 5px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.045em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1.5px solid transparent;
  transition: transform var(--duration) var(--ease), filter var(--duration) var(--ease);
}
.sticky-cta .scta svg { width: 19px; height: 19px; flex: none; }
.sticky-cta .scta span { line-height: 1; }
.sticky-cta .scta:active { transform: translateY(1px); }
.sticky-cta a + a { border-left: none; }   /* the old hairline divider is gone */

.sticky-cta .scta-call { background: var(--copper); color: #14181d; border-color: var(--copper); }
.sticky-cta .scta-text { background: #263140; color: #f0f2f4; border-color: #46566b; }
.sticky-cta .scta-book { background: transparent; color: var(--copper); border-color: var(--copper); }

/* "Book Online" at the 15px legibility floor needs about 109px with its icon,
   and a 320px screen only affords 97px per button. Rather than shrink the type
   below the floor, the labels shorten to Call / Text / Book, which still say
   exactly what the button does. */
.scta-short { display: none; }
@media (max-width: 379px) {
  .sticky-cta .scta { letter-spacing: 0.02em; gap: 0.3rem; }
  .sticky-cta .scta svg { width: 17px; height: 17px; }
  .scta-long  { display: none; }
  .scta-short { display: inline; }
}
@media (max-width: 820px) {
  body { padding-bottom: 78px; }
}

/* ---------------------------------------------------------------------------
   HERO PHONE BLOCK, RAISED.
   Jay: "the phone number is not actually in the display ... move it slightly
   higher so that it fits, but also not so high that it's crammed."
   The gap above it was 2rem of margin plus the hero's own bottom padding. Both
   trimmed on phones, which lifts the number and the line under it clear of the
   sticky bar without tightening the copy above.
   --------------------------------------------------------------------------- */
@media (max-width: 820px) {
  .hero-mid .hero-ctas { margin-top: 1.1rem; }
  .hero-mid { padding-bottom: 2.4rem; }
  .phone-hero.mt-0 { margin-top: 0; }
}

/* ---------------------------------------------------------------------------
   SHORT PHONES: get the phone number above the fold without cramming.

   Measured on a 393x700 viewport, which is an iPhone 15 Pro with Safari's
   toolbars showing. The phone number ended 58px below the sticky bar. The space
   above it breaks down as: badge pill 69px plus 18px margin, headline 215px,
   deck 55px, paragraph 121px.

   The badge pill is the right thing to give up on a short screen. It costs 87px
   and repeats the service area, which the hero
   paragraph, the footer, the page title and the schema all say too. The phone
   number is the conversion action and nothing else on the page replaces it.

   Margins are trimmed a little alongside it. No FONT SIZE changes: shrinking
   type is exactly the "crammed" look to avoid.
   --------------------------------------------------------------------------- */
@media (max-width: 820px) and (max-height: 745px) {
  .hero-mid .badge-pill { display: none; }
  .hero-mid { padding-top: 0.6rem; }
  .hero-mid .hero-lines { margin-bottom: 0.7rem; }
  .hero-mid .hero-deck  { margin-bottom: 0.6rem; }
  .hero-mid .hero-ctas  { margin-top: 0.7rem; }
}

/* Very short phones (iPhone SE at 667, 360x640 Androids). Both were within 10px
   of fitting. Line-height is tightened, never font-size: denser leading reads as
   deliberate typesetting, smaller type reads as crammed, which is the thing Jay
   asked me not to do. */
@media (max-width: 820px) and (max-height: 700px) {
  .hero-mid .hero-lines { line-height: 0.88; }
  .hero-mid .hero-sub   { line-height: 1.42; }
  .hero-mid .phone-note { margin-top: 0.15rem; }
  .hero-mid { padding-bottom: 1.6rem; }
}

/* iPhone SE (667) and 360x640 Androids need about 15 more pixels. The line under
   the number, "One number. A person answers.", is the least load-bearing thing
   in the hero: the number itself is the conversion action, and the same promise
   is made in the hero paragraph and on the contact page. It steps aside on the
   shortest screens only. */
@media (max-width: 820px) and (max-height: 690px) {
  .hero-mid .phone-note { display: none; }
  .hero-mid { padding-bottom: 1rem; }
}

/* ===========================================================================
   FOUR FIXES FROM JAY'S iPHONE REVIEW, 2026-08-14
   =========================================================================== */

/* 1. BUTTON WITH NO HORIZONTAL PADDING.
   Jay: "the border is too close to the edges of the words". It was closer than
   that: the padding was literally 9.6px 0px. A max-width:720px rule meant to
   give bare text links a 44px tap target, `.section > .wrap > p > a:only-child
   { padding: 0.6rem 0 }`, also matched this .btn because the button sits inside
   a <p>. Buttons are now excluded from that rule and this one is solid copper
   with an arrow so it reads as the primary next step, not a hairline box. */
@media (max-width: 720px) {
  .section > .wrap > p > a.btn:only-child,
  .section-alt > .wrap > p > a.btn:only-child,
  .section-dark > .wrap > p > a.btn:only-child {
    padding: 0.95rem 1.6rem;
    /* That same rule also forces display:inline-block, which killed the flex
       gap and left the arrow jammed against the last letter. */
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
  }
}
.btn-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  border-radius: 4px;
}
.btn-arrow span { transition: transform var(--duration) var(--ease); }
.btn-arrow:hover span { transform: translateX(4px); }

/* 2. TRUST CHIPS.
   Jay: "it kind of goes in two lines, but there's a lot of space in there ...
   too bland and kind of awkward-looking". Three uppercase mono pills of unequal
   height, one wrapping to three lines with a big hollow gap. Pills are the wrong
   container for a sentence. A checked list reads faster, sits flush, and cannot
   produce a ragged half-empty pill. */
.trust-list {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.85rem;
}
.trust-list li {
  position: relative;
  padding-left: 2.1rem;
  font-size: 1.02rem;
  line-height: 1.45;
  color: var(--ink);
}
.trust-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.12em;
  width: 1.35rem;
  height: 1.35rem;
  border-radius: 50%;
  background: var(--copper);
  /* a check mark, drawn rather than a font glyph so it never falls back */
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z' fill='%23000'/%3E%3C/svg%3E") center / 78% no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z' fill='%23000'/%3E%3C/svg%3E") center / 78% no-repeat;
}
.section-dark .trust-list li { color: var(--on-dark); }

/* 3. CITY AND ZIP CARDS.
   Jay: "you can't really tell that you can click on them ... is this a list, or
   is this clickable?" It was a two-column table of city names with grey ZIP
   numbers ranged right, which reads as printed data. Now each city is a card
   with a copper accent, and every ZIP is its own bordered chip, so both the
   city and each ZIP look like the links they are. */
.areas-index { grid-template-columns: 1fr; gap: clamp(1.4rem, 1rem + 2vw, 2.6rem); }
.area-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 15.5rem), 1fr)); gap: 0.85rem; }
.area-col-wide .area-list { column-count: initial; display: grid; }

.area-card {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line);
  border-left: 4px solid var(--copper);
  border-radius: 6px;
  padding: 0.95rem 1rem 0.85rem;
  transition: border-color var(--duration) var(--ease),
              box-shadow var(--duration) var(--ease),
              transform var(--duration) var(--ease);
}
.area-card:hover, .area-card:focus-within {
  border-color: var(--copper);
  box-shadow: 0 10px 22px -16px rgba(20, 24, 29, 0.55);
  transform: translateY(-2px);
}
.area-card-name {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.28rem;
  letter-spacing: 0.02em;
  color: var(--ink);
  text-decoration: none;
}
.area-card-zips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.6rem; }
.zip-tag {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 0.2rem 0.62rem;
  border: 1px solid var(--copper);
  border-radius: 999px;
  background: var(--copper-tint);
  color: var(--copper-ink);
  font-family: var(--font-plate);
  font-size: 0.86rem;
  letter-spacing: 0.04em;
  text-decoration: none;
  transition: background var(--duration) var(--ease), color var(--duration) var(--ease);
}
.zip-tag:hover, .zip-tag:focus-visible { background: var(--copper); color: #14181d; }
.area-card-go {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.7rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--copper-ink);
  text-decoration: none;
}
.area-card-go span { transition: transform var(--duration) var(--ease); }
.area-card:hover .area-card-go span { transform: translateX(4px); }
.section-dark .area-card { background: rgba(255,255,255,0.045); border-color: rgba(214,226,240,0.2); }
.section-dark .area-card-name { color: var(--on-dark); }
.section-dark .area-card-go { color: var(--copper); }
.section-dark .zip-tag { background: rgba(201,122,58,0.14); color: var(--copper); }

@media (max-width: 720px) {
  .areas-index { grid-template-columns: 1fr; }
}

/* 4. TWO BUTTONS SHARING AN EDGE ON THE SECOND-OPINION PAGE.
   Jay: "the two buttons, and they're overlapping each other". Root cause: the
   container is .hero-cta, SINGULAR, and every rule in the stylesheet targets
   .hero-ctas, PLURAL. So it had no display, no gap, and the two bordered
   buttons stacked with their edges touching at exactly the same y.
   It now uses the same flex layout as its plural sibling, and on phones both
   buttons go full width so they read as a deliberate pair. */
.hero-cta {
  margin-top: 1.25rem;
  display: flex;
  gap: 0.85rem;
  flex-wrap: wrap;
  align-items: center;
}
@media (max-width: 620px) {
  .hero-cta { flex-direction: column; align-items: stretch; }
  .hero-cta .btn { width: 100%; text-align: center; }
}

/* Structural hooks the markup relies on. Both were dropped by the dead-CSS
   sweep because they carried no declarations at the time, which left classes in
   the HTML with nothing behind them. Declared explicitly so the undefined-class
   check stays meaningful rather than being taught to ignore them. */
.area-col { min-width: 0; }
.dg-stage { transform-box: fill-box; }

/* The new area cards and trust list shipped under the site's own floors: ZIP
   chips at 13.8px against a 14px minimum, and three link types at 25 to 34px
   against the 44px touch target. Caught by mobile_audit, not by eye. */
.zip-tag {
  font-size: 0.95rem;
  min-height: 44px;
  padding: 0.35rem 0.85rem;
}
.area-card-name {
  min-height: 44px;
  display: flex;
  align-items: center;
}
.area-card-go {
  min-height: 44px;
  margin-top: 0.35rem;
}
.trust-list li { font-size: 1.0625rem; }
