/* Luxe Ducts, Chicagoland.
   Palette taken from the client's own surfaces: #FE017F sampled from the logo
   pixels, #F5037C is the colour they themselves set in their GoHighLevel chat
   widget, #A50D59 and #D61F7A are their own site tokens (--brand-pink 330 85% 35%
   and --brand-pink-light 330 75% 48%). Black and white are the rest of the mark.

   CONTRAST PASS 2026-09-05. The logo pink #FE017F carries white text on every
   primary button, the form submit, the mobile call bar and the numbered step
   counters, and white on it measures 3.80:1, under the 4.5:1 AA floor for text
   that size. --pink is now the same hue at the same saturation, five points
   darker in lightness, hsl(330 99% 44%). That measures 4.76:1 and is
   indistinguishable from the logo pink side by side. --pink-soft is the pale
   rose used for text OVER the hero photographs; it dipped to 1.86:1 in the
   bright patches of the Glen Ellyn hero, so it went LIGHTER, not darker,
   because that text sits on dark.

   Type: Archivo Black for display, Barlow for body. Both stay. The third face,
   Pinyon Script, was removed on 2026-09-05. It was defended in this comment as
   being the logo. It is not: the "Luxe" in the mark is a rounded brush script
   with a swash, and Pinyon is formal copperplate off a wedding invitation.
   Refinement on this brand comes from spacing, weight and restraint.
   The rubber duck is the mascot and appears as a ghost watermark, in the seam of
   the divider, and as the marker on lists. */

:root {
  --pink: #E00170;
  --pink-hot: #F5037C;
  --pink-mid: #D61F7A;
  --pink-deep: #A50D59;
  --pink-soft: #FFAFC9;
  --pink-wash: rgba(224, 1, 112, 0.10);

  --ink: #0A0A0A;
  --ink-soft: #17151A;
  --ink-line: #2A2430;

  --color-bg: #FFFFFF;
  --color-surface: #FBF4F8;
  --color-surface-2: #F4E9F0;

  --color-text: #1B1620;
  --color-text-light: #635C6B;
  --color-on-dark: #FFFFFF;
  --color-on-dark-muted: #CBBFC7;

  --color-border: #EBDDE6;
  --color-google-star: #FBBC04;

  --font-display: 'Archivo Black', 'Arial Black', 'Helvetica Neue', sans-serif;
  --font-body: 'Barlow', 'Segoe UI', sans-serif;

  --container: 1200px;
  --radius: 10px;
  --radius-lg: 16px;
  --shadow-sm: 0 2px 10px rgba(10, 10, 10, 0.07);
  --shadow-md: 0 10px 28px rgba(10, 10, 10, 0.12);
  --shadow-lg: 0 22px 52px rgba(10, 10, 10, 0.20);
  --ease: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --z-nav: 1000;
  --z-cta: 1100;
  /* The fixed call bar's exact height. The sticky nav's top offset, the body's
     top padding, the drawer's top padding and the drawer close button all read
     THIS, so they cannot drift apart when a font or a font-size changes.
     Zero here because the bar only exists at 768px and below; the real height
     is set inside that media query. */
  --cta-bar-h: 0px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.68;
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--pink-deep); }
p a { font-weight: 700; }
.container { max-width: var(--container); margin: 0 auto; padding: 0 24px; }
.text-center { text-align: center; }

h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 400; line-height: 1.14; letter-spacing: -0.01em; }
/* The display face ships ONE weight. Every rule that uses it says font-weight: 400 (above and
   below), and this stops the browser smearing a fake bold over it anywhere a heavier weight
   leaks in (a strong inside a display element, an inherited 700). The body face loads real
   400 to 700 weights, so it is unaffected. Italic synthesis is left alone. Font gate, 2026-09-07. */
html { font-synthesis: style; font-synthesis-weight: none; }
h2, h3, h4 { text-transform: none; }

/* Founder pull quote. Barlow italic at reading size with a brand rule beside it.
   This replaced a copperplate script face on 2026-09-05. */
.pullquote { border-left: 4px solid var(--pink); padding: 2px 0 2px 20px; margin: 22px 0 18px; font-size: clamp(19px, 1.7vw, 23px); font-style: italic; font-weight: 500; line-height: 1.45; letter-spacing: 0.005em; color: var(--pink-deep); }

/* ---------- buttons ---------- */
.btn {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 15px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 16px 30px;
  border-radius: 999px;
  line-height: 1;
  cursor: pointer;
  border: 2px solid transparent;
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), background 0.25s var(--ease), color 0.25s var(--ease);
}
.btn--primary { background: var(--pink); color: #fff; box-shadow: 0 6px 18px rgba(224, 1, 112, 0.34); }
.btn--primary:hover { background: var(--pink-mid); transform: translateY(-2px); box-shadow: 0 10px 24px rgba(224, 1, 112, 0.42); }
.btn--dark { background: var(--ink); color: #fff; }
.btn--dark:hover { background: var(--pink-deep); transform: translateY(-2px); }
.btn--outline { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn--outline:hover { background: var(--ink); color: #fff; }
.btn--outline-light { background: rgba(255, 255, 255, 0.08); color: #fff; border-color: rgba(255, 255, 255, 0.85); }
.btn--outline-light:hover { background: #fff; color: var(--ink); }
.btn--sm { padding: 12px 20px; font-size: 13px; }
.btn-pair { display: flex; gap: 14px; flex-wrap: wrap; }

/* ---------- mobile sticky CTA ---------- */
.mobile-cta-bar { display: none; }
@media (max-width: 768px) {
  :root { --cta-bar-h: 52px; }   /* measured: the bar renders at exactly 52.00px */
  .mobile-cta-bar { display: flex; position: fixed; bottom: 0; left: 0; right: 0; z-index: var(--z-cta); height: var(--cta-bar-h); box-sizing: content-box; padding-bottom: env(safe-area-inset-bottom, 0px); }
  /* one line, always. A wrapped label would make the bar taller than the
     offset the body padding and the sticky nav are both set to. */
  .mobile-cta-bar a { flex: 1; height: var(--cta-bar-h); display: flex; align-items: center; justify-content: center; padding: 0 4px; text-align: center; font-family: var(--font-display); font-weight: 400; font-size: clamp(0.6rem, 3.1vw, 0.78rem); letter-spacing: 0.01em; text-transform: uppercase; text-decoration: none; white-space: nowrap; }
  .mobile-cta-bar__primary { background: var(--pink); color: #fff; }
  .mobile-cta-bar__call { background: var(--ink); color: #fff; }
  /* the sticky nav parks BELOW the fixed bar, never under it. Both numbers read
     the one variable so they cannot drift apart again. */
  body { padding-bottom: calc(var(--cta-bar-h) + env(safe-area-inset-bottom, 0px)); }
  body .nav { top: 0; }
}

/* ---------- utility bar ---------- */
.utility-bar { background: var(--ink); color: #D8CBD3; font-size: 13.5px; padding: 9px 0; position: relative; z-index: 1001; }
.utility-bar .container { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.utility-bar__item { display: inline-flex; align-items: center; gap: 7px; }
.utility-bar__item svg { width: 15px; height: 15px; color: var(--pink); }
.utility-bar__actions { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
/* inline-flex from the phone tap-target rule swallows the whitespace text node
   between the label span and the number, so the gap is set explicitly */
.utility-bar__phone { display: inline-flex; align-items: baseline; gap: 6px; color: #fff; font-weight: 700; text-decoration: none; letter-spacing: 0.01em; }
.utility-bar__phone:hover { color: var(--pink-soft); }
.utility-bar__phone span { color: var(--pink-soft); font-weight: 600; }
@media (max-width: 900px) { .utility-bar__where { display: none; } .utility-bar .container { justify-content: center; } }

/* ---------- nav ---------- */
.nav { background: #fff; position: sticky; top: 0; z-index: var(--z-nav); box-shadow: 0 1px 0 var(--color-border), 0 6px 20px rgba(10, 10, 10, 0.07); }
.nav .container { display: flex; align-items: center; gap: 22px; min-height: 84px; }
.nav__logo { flex-shrink: 0; display: block; }
.nav__logo img { width: auto; height: 56px; }
.nav__links { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.nav__link, .nav__dropdown-toggle {
  font-family: var(--font-body); font-weight: 700; font-size: 15px; color: var(--ink);
  background: none; border: none; cursor: pointer; text-decoration: none;
  padding: 10px 12px; border-radius: 8px; display: inline-flex; align-items: center; gap: 5px;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.nav__link:hover, .nav__dropdown-toggle:hover { background: var(--pink-wash); color: var(--pink-deep); }
.nav__dropdown { position: relative; }
.nav__dropdown-menu {
  position: absolute; top: calc(100% + 10px); left: 0; min-width: 268px;
  background: var(--ink); border: 1px solid var(--ink-line);
  border-radius: 12px; padding: 8px; box-shadow: var(--shadow-lg);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease), visibility 0.3s;
  z-index: 1002;
}
.nav__dropdown:hover .nav__dropdown-menu, .nav__dropdown.open .nav__dropdown-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.nav__dropdown-item { display: block; padding: 10px 14px; color: #E9DEE5; text-decoration: none; font-size: 14.5px; font-weight: 600; border-radius: 8px; transition: background 0.2s var(--ease), color 0.2s var(--ease); }
.nav__dropdown-item:hover { background: var(--pink); color: #fff; }
.nav__actions { display: flex; gap: 10px; flex-shrink: 0; }
.nav__hamburger { display: none; flex-direction: column; gap: 5px; background: none; border: none; cursor: pointer; padding: 8px; }
.nav__hamburger span { width: 26px; height: 3px; border-radius: 2px; background: var(--ink); transition: transform 0.35s var(--ease), opacity 0.35s var(--ease); }
.nav__hamburger.active span:nth-child(1) { transform: rotate(45deg) translate(6px, 6px); }
.nav__hamburger.active span:nth-child(2) { opacity: 0; }
.nav__hamburger.active span:nth-child(3) { transform: rotate(-45deg) translate(5px, -5px); }
.nav-overlay { position: fixed; inset: 0; background: rgba(10, 10, 10, 0.6); opacity: 0; visibility: hidden; transition: opacity 0.35s var(--ease); z-index: 999; }
.nav-overlay.active { opacity: 1; visibility: visible; }
.nav__close { display: none; }

/* THE SCROLL LOCK GOES ON THE ROOT, NEVER ON <body>. js/main.js used to set
   body.style.overflow = 'hidden' while the drawer was open. That only happens
   to work here because <html> has no overflow of its own, so body's overflow
   propagates to the viewport. The moment anybody adds overflow-x to html, as
   the sibling builds have, <body> becomes the scroll container, position:sticky
   on .nav is measured against it, and the whole header including the hamburger
   jumps thousands of pixels off the top of the screen with the drawer open.
   Locking <html> cannot go wrong that way. */
html.menu-open { overflow: hidden; }

@media (max-width: 1100px) {
  .nav__hamburger { display: flex; margin-left: auto; }
  .nav__actions { display: none; }
  .nav__links {
    position: fixed; top: 0; right: -100%; width: 86%; max-width: 400px; height: 100vh;
    background: var(--ink); flex-direction: column; align-items: stretch;
    padding: 84px 24px 40px; gap: 2px; transition: right 0.4s var(--ease-out); z-index: 1005; overflow-y: auto; margin: 0;
  }
  .nav__links.open { right: 0; }
  .nav__link, .nav__dropdown-toggle { color: #fff; width: 100%; justify-content: space-between; font-size: 17px; padding: 14px 12px; }
  .nav__dropdown-menu { position: static; opacity: 1; visibility: visible; transform: none; display: none; box-shadow: none; border: none; background: rgba(255, 255, 255, 0.06); margin: 4px 0 8px; }
  .nav__dropdown.open .nav__dropdown-menu { display: block; }

  /* ---- open drawer stacking, fixed 2026-09-05 ----------------------------
     .nav is position:sticky with a z-index, so it forms a stacking context and
     the drawer inside it could never outrank .nav's SIBLINGS: the fixed call
     bar (z 1100) and the utility bar (z 1001). The top 149px of the open panel
     sat behind those two, which hid the first menu group, "Cleaning", and sent
     a tap on it to the phone link instead. Lifting the whole nav while the
     drawer is open takes the panel, the hamburger and the close button with it. */
  body.menu-open .nav { z-index: 1200; }
  /* the scrim has to clear the two bars as well, or they stay at full
     brightness in the strip beside the open panel */
  body.menu-open .nav-overlay { z-index: 1150; }
  /* the nav bar itself has to ride above that scrim so the hamburger stays
     tappable, so while the panel is open the bar goes transparent instead of
     leaving a bright white stub in the strip beside it */
  body.menu-open .nav { background: var(--ink); box-shadow: none; }
  /* opacity alone left an INVISIBLE but still tappable "go home" link sitting in
     the dark dismiss strip beside the open drawer: the anchor kept pointer-events
     auto at z 1200, above the 1150 scrim, so a thumb landing top-left to close the
     menu silently navigated to index.html instead. pointer-events:none hands those
     taps to the scrim, which is what closes the menu. Fixed 2026-09-05. */
  body.menu-open .nav__logo { opacity: 0; pointer-events: none; }
  /* the hamburger is a static child of .nav, so the positioned panel (z 1005)
     painted over it and it could not be tapped to close the menu. It stays
     above the panel and stays tappable, so a second tap in the same place
     still closes the menu, but its bars are hidden while the panel is open:
     the panel covers the whole right side of the screen, so a visible X
     stranded halfway down the menu list read as a rendering fault. The visible
     close affordance is .nav__close at the top right of the panel. */
  .nav__hamburger { position: relative; z-index: 1010; }
  body.menu-open .nav__hamburger span { opacity: 0; }

  /* A real close control inside the drawer. Fixed, not absolute, so it stays
     pinned at the panel's top right even when a long submenu scrolls.
     right:80px, not 16px, so it never lands on top of the hamburger. Above
     768px there is no call bar, the nav parks at y=0, and a 16px inset put the
     two controls in the same 46px box: whichever won the stack made the other
     untappable. 80px keeps a clear 10px gutter between them at every width. */
  .nav__close {
    display: flex; position: fixed; top: 14px; right: 80px;
    width: 46px; height: 46px; align-items: center; justify-content: center;
    padding: 0; border-radius: 50%; cursor: pointer;
    background: rgba(255, 255, 255, 0.10); border: 1px solid rgba(255, 255, 255, 0.32);
    color: #fff; opacity: 0; visibility: hidden; z-index: 6;
    transition: opacity 0.3s var(--ease), visibility 0.3s, background 0.25s var(--ease);
  }
  .nav__close:hover { background: var(--pink); border-color: var(--pink); }
  .nav__close svg { width: 22px; height: 22px; display: block; }
  .nav__links.open .nav__close { opacity: 1; visibility: visible; }
}

/* ---------- brand devices ----------
   1. duck ghost watermark  2. pink runner stripe  3. duck notch seam */
.duck-ghost {
  position: absolute; right: -40px; bottom: -30px; width: clamp(180px, 22vw, 320px);
  opacity: 0.045; pointer-events: none; z-index: 0;
}
.duck-ghost--left { right: auto; left: -50px; top: -40px; bottom: auto; }
.runner-stripe { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.runner-stripe::before {
  content: ''; position: absolute; top: -20%; left: -10%; width: 34%; height: 140%;
  background: linear-gradient(180deg, rgba(224, 1, 112, 0.10), rgba(224, 1, 112, 0.02));
  transform: skewX(-14deg);
}
.section-divider { position: relative; line-height: 0; }
.section-divider--over { position: absolute; left: 0; right: 0; bottom: -1px; z-index: 3; pointer-events: none; }

/* ---------- hero ---------- */
.hero { position: relative; background: linear-gradient(140deg, #1A0713 0%, var(--ink) 58%, #12060E 100%); color: #fff; overflow: hidden; }
.hero__bg { position: absolute; inset: 0; background-size: cover; background-position: center; }
/* The right end of this wash used to be 42% and the hero photographs showed
   through bright enough that the pale pink eyebrow measured 1.86:1 in the
   worst patch of the Glen Ellyn hero. Deeper on the pink end only; the left
   two stops are near enough unchanged and the photograph still reads. */
.hero__bg::after { content: ''; position: absolute; inset: 0; background: linear-gradient(100deg, rgba(10, 10, 10, 0.93) 6%, rgba(20, 6, 14, 0.84) 44%, rgba(120, 8, 64, 0.66) 100%); }
.hero .container { position: relative; z-index: 2; }
.hero--home .hero__content { padding: 92px 0 128px; max-width: 780px; }
.hero--sub .hero__content { padding: 36px 0 104px; max-width: 740px; }
.hero--sub .breadcrumbs { padding-top: 54px; }
@media (max-width: 1100px) { .hero--sub .breadcrumbs { padding-top: 22px; } }
.hero__eyebrow { font-family: var(--font-body); font-weight: 700; font-size: 13px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--pink-soft); margin-bottom: 14px; }
/* ===== HERO RATING BADGE ROW =============================================
   The row NEVER wraps and NEVER stacks, at any width, at any badge count.

   What broke before: each badge was an HTML lockup, a logo beside a couple of
   spans of text. An HTML lockup cannot compress narrower than its own words,
   so two of them would not fit a phone column and the row fell into a stack.

   What fixes it: each badge is now one inline <svg viewBox="0 0 193 60">. An
   SVG with a viewBox has NO minimum content width, so it shrinks freely, the
   same way the flat image badges on the reference sites do. Three properties
   carry that, and removing ANY ONE of them puts the stacking back:
     flex: 1 1 0     each badge takes an equal share of the row
     min-width: 0    permits shrinking below content size. The forgotten one.
     max-width       stops a lone badge ballooning across the whole row
   Measured on a real 375px phone: 1 badge 193px, 2 badges 178px each,
   3 badges 117px each, 4 badges 86px each. One row every time.

   _gate-badge-row.js re-measures all of this in a real browser at 375, 414
   and 768 and fails the build if the row ever uses more than one line. */
:root {
  --rbadge-ink: var(--color-on-dark);  /* the marks and the rating line, on this dark hero */
  --rbadge-star: #F6AB26;                   /* measured star gold; NOT the Google #FBBC04 */
}
/* >>> rating-badge component: generated by .skills/client-website/components/rbadge-css.js. Do not edit inside the markers. <<< */
.rbadges {
  display: flex;
  flex-wrap: nowrap;              /* THE FIX. It physically cannot stack. */
  align-items: center;
  justify-content: flex-start;
  gap: 20px;
  width: 100%;
  max-width: 520px;
  margin: 0 0 20px;
  padding: 0;
  background: none;               /* no panel, no pill, no card behind the row */
  border: 0;
}
.rbadges[data-count="3"] { gap: 12px; }
.rbadges[data-count="4"] { gap: 10px; }
.rbadges__item {
  flex: 1 1 0;
  min-width: 0;                   /* REQUIRED. Without it the row breaks. */
  max-width: 193px;
  display: block;
  line-height: 0;
  /* The item is an <a>, so without this it inherits the site's link colour. Nothing inside the
     badge is painted with that colour, but a contrast sweep reading currentColor would measure a
     colour the badge never paints. Pin it to the same token the artwork uses so the two agree. */
  color: var(--rbadge-ink, #fff);
}
.rbadges__item:focus-visible { outline: 3px solid var(--rbadge-focus, currentColor); outline-offset: 4px; border-radius: 2px; }
.rbadge { display: block; width: 100%; height: auto; aspect-ratio: 193 / 60; color: var(--rbadge-ink, #fff); }
.rbadge text { fill: currentColor; font-family: var(--font-body, inherit); }
.rbadge path[fill="#F6AB26"] { fill: var(--rbadge-star, #F6AB26); }
@media (max-width: 768px) { .rbadges { max-width: none; gap: 12px; } }
@media (max-width: 400px)  { .rbadges { gap: 8px; } }
/* A light section flips ONLY the ink. The Google G keeps Google's colours on any ground. */
.rbadges--dark .rbadge { color: #0E1A2B; }
/* <<< end rating-badge component >>> */
.hero__title { font-size: clamp(31px, 4.3vw, 54px); margin-bottom: 14px; }
.hero__count { font-family: var(--font-display); font-weight: 400; font-size: clamp(17px, 2vw, 23px); color: var(--pink-soft); text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 14px; border-bottom: 4px solid var(--pink); display: inline-block; padding-bottom: 5px; }
.hero__text { font-size: clamp(16px, 1.5vw, 19px); color: #EADFE6; max-width: 660px; margin-bottom: 22px; }
.hero__trust { display: flex; flex-wrap: wrap; gap: 10px 26px; margin-bottom: 28px; }
.hero__trust-item { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: 15px; color: #E4D8E0; }
.hero__trust-item svg { width: 17px; height: 17px; color: var(--pink); flex-shrink: 0; }
.hero__actions { display: flex; gap: 14px; flex-wrap: wrap; }

/* ---------- trust strip ---------- */
.trust-strip { position: relative; z-index: 4; margin-top: -44px; margin-bottom: 16px; }
.trust-strip__card {
  background: #fff; border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
  border-top: 5px solid var(--pink);
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; padding: 22px 26px;
}
.trust-strip__item { display: flex; align-items: center; gap: 12px; }
.trust-strip__icon { width: 44px; height: 44px; border-radius: 50%; background: var(--pink-wash); color: var(--pink-deep); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.trust-strip__icon svg { width: 22px; height: 22px; }
.trust-strip__label { font-family: var(--font-display); font-weight: 400; font-size: 14.5px; color: var(--ink); }
.trust-strip__sub { font-size: 13px; color: var(--color-text-light); line-height: 1.45; }
@media (max-width: 1024px) { .trust-strip__card { grid-template-columns: repeat(2, 1fr); gap: 18px; } }
@media (max-width: 560px) { .trust-strip__card { grid-template-columns: 1fr; } }

/* ---------- credentials strip ---------- */
.creds { background: var(--color-surface); border-top: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); padding: 26px 0; }
.creds__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px 26px; }
.creds__pill { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink); }
.creds__pill svg { width: 15px; height: 15px; color: var(--pink); flex-shrink: 0; }
.creds__badges { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 22px; margin-top: 18px; }
.creds__badges img { height: 52px; width: auto; opacity: 0.95; }
@media (max-width: 640px) { .creds__badges img { height: 42px; } }

/* ---------- sections ---------- */
.section { position: relative; padding: 92px 0; }
.section--surface { background: var(--color-surface); }
.section--dark { background: var(--ink); color: var(--color-on-dark-muted); }
/* Clips the duck ghost watermark. Only used on sections that carry one, because
   overflow:hidden on an ancestor kills position:sticky and the lead form column
   depends on it. Added after the homepage measured 1480px wide at a 1440 viewport. */
.section--ghost { overflow: hidden; }
.section--dark .section-title { color: #fff; }
.section--dark p { color: var(--color-on-dark-muted); }
.section > .container { position: relative; z-index: 1; }
.section-subtitle { font-family: var(--font-body); font-weight: 800; font-size: 13px; letter-spacing: 0.17em; text-transform: uppercase; color: var(--pink-deep); margin-bottom: 10px; }
.section--dark .section-subtitle { color: var(--pink-soft); }
.section-title { font-size: clamp(27px, 3.2vw, 42px); color: var(--ink); margin-bottom: 18px; }
.section-title--underline { position: relative; padding-bottom: 18px; }
.section-title--underline::after { content: ''; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 92px; height: 5px; border-radius: 3px; background: linear-gradient(90deg, var(--pink) 62%, var(--ink) 62%); }
.section-title--underline.left::after { left: 0; transform: none; }
.section__footer { text-align: center; margin-top: 44px; }
.text-center .section-title { margin-left: auto; margin-right: auto; }
.text-center > p { color: var(--color-text-light); }
.prose { max-width: 810px; margin-left: auto; margin-right: auto; }
.prose p { margin-bottom: 18px; }
.split > div > p, .band__grid > div > p, .lead-split__copy > p { margin-bottom: 16px; }

/* ---------- cards ---------- */
.card-grid { display: grid; gap: 26px; margin-top: 44px; }
.card-grid--2 { grid-template-columns: repeat(2, 1fr); }
.card-grid--3 { grid-template-columns: repeat(3, 1fr); }
.card-grid--4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1024px) { .card-grid--3, .card-grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 700px) { .card-grid--2, .card-grid--3, .card-grid--4 { grid-template-columns: 1fr; } }

.svc-card { position: relative; display: flex; flex-direction: column; background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); overflow: hidden; transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease); }
.svc-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); }
.svc-card__media { position: relative; display: block; aspect-ratio: 16 / 9; background: var(--color-surface-2); overflow: hidden; }
.svc-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s var(--ease-out); }
.svc-card:hover .svc-card__media img { transform: scale(1.045); }
.svc-card__media::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 6px; background: linear-gradient(90deg, var(--pink) 62%, var(--ink) 62%); }
.svc-card__body { display: flex; flex-direction: column; flex: 1 1 auto; padding: 24px 26px 28px; }
.svc-card--icon::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 6px; background: linear-gradient(90deg, var(--pink) 62%, var(--ink) 62%); }
.svc-card--icon .svc-card__body { padding-top: 30px; }
.svc-card__icon { width: 48px; height: 48px; border-radius: 14px; background: var(--ink); color: var(--pink-soft); display: flex; align-items: center; justify-content: center; margin-bottom: 16px; }
.svc-card__icon svg { width: 26px; height: 26px; }
.svc-card__tag { align-self: flex-start; max-width: 100%; margin-bottom: 12px; background: var(--pink-wash); color: var(--pink-deep); font-family: var(--font-body); font-weight: 800; font-size: 11px; letter-spacing: 0.09em; text-transform: uppercase; padding: 6px 12px; border-radius: 999px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.svc-card h3 { font-size: 21px; color: var(--ink); margin-bottom: 10px; }
.svc-card p { color: var(--color-text-light); font-size: 15.5px; margin-bottom: 20px; }
.svc-card__body .btn { margin-top: auto; align-self: flex-start; }
@media (max-width: 700px) { .svc-card__body { padding: 22px 22px 26px; } }

.icon-card { position: relative; background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 30px 26px; box-shadow: var(--shadow-sm); transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease); }
.icon-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.icon-card__icon { width: 52px; height: 52px; border-radius: 50%; background: var(--pink-wash); color: var(--pink-deep); display: flex; align-items: center; justify-content: center; margin-bottom: 16px; }
.icon-card__icon svg { width: 25px; height: 25px; }
.icon-card h3 { font-size: 19px; color: var(--ink); margin-bottom: 8px; }
.icon-card p { font-size: 15px; color: var(--color-text-light); }
.icon-card--num .icon-card__icon { background: var(--pink); color: #fff; font-family: var(--font-display); font-weight: 400; font-size: 20px; }

.review-card { background: #fff; border: 1px solid var(--color-border); border-left: 5px solid var(--pink); border-radius: var(--radius-lg); padding: 28px; box-shadow: var(--shadow-sm); position: relative; }
.review-card__g { position: absolute; top: 24px; right: 24px; }
.review-card__g svg { width: 25px; height: 25px; }
.review-card__stars { display: flex; gap: 2px; color: var(--color-google-star); margin-bottom: 14px; }
.review-card__stars svg { width: 18px; height: 18px; }
.review-card__text { font-size: 15.5px; color: var(--color-text); margin-bottom: 16px; white-space: pre-line; }
.review-card__author { font-family: var(--font-display); font-weight: 400; color: var(--ink); font-size: 15px; }
.review-card__when { font-size: 13px; color: var(--color-text-light); }
.reviews__cta { display: flex; justify-content: center; gap: 16px; flex-wrap: wrap; margin-top: 44px; }
.spotlight { max-width: 780px; margin: 40px auto 0; }

/* ---------- areas ---------- */
.area-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 40px; }
@media (max-width: 900px) { .area-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .area-grid { grid-template-columns: 1fr; } }
.area-card { background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius); padding: 18px 20px; box-shadow: var(--shadow-sm); transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease); }
.area-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--pink); }
.area-card__city { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-display); font-weight: 400; font-size: 16px; color: var(--ink); text-decoration: none; margin-bottom: 6px; }
.area-card__city:hover { color: var(--pink-deep); }
.area-card__city svg { width: 16px; height: 16px; color: var(--pink); }
/* the separator dots inherit this colour. It used to be --color-border, which
   is a hairline colour, 1.31:1 on white, so the three service links ran together. */
.area-card__links { display: flex; gap: 8px; font-size: 13.5px; color: var(--color-text-light); flex-wrap: wrap; }
.area-card__links a { color: var(--color-text-light); text-decoration: none; font-weight: 700; }
.area-card__links a:hover { color: var(--pink-deep); }

/* ---------- lists, steps, stats, split ---------- */
.check-list { list-style: none; columns: 2; gap: 40px; margin-top: 20px; max-width: 760px; margin-left: auto; margin-right: auto; }
@media (max-width: 640px) { .check-list { columns: 1; } }
.check-list li { display: flex; align-items: center; gap: 10px; padding: 7px 0; break-inside: avoid; }
.check-list svg { width: 17px; height: 17px; color: var(--pink); flex-shrink: 0; }
.check-list a { font-weight: 700; text-decoration: none; }
.check-list a:hover { text-decoration: underline; }
.check-list li span { font-weight: 600; color: var(--color-text); }
.icon-card .check-list { columns: 1; margin-top: 12px; max-width: none; }

.step-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px; margin-top: 44px; }
@media (max-width: 900px) { .step-grid { grid-template-columns: 1fr; } }
.step { background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 34px 28px; box-shadow: var(--shadow-sm); }
.step__num { font-family: var(--font-display); font-weight: 400; font-size: 26px; color: #fff; background: var(--pink); width: 60px; height: 60px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-bottom: 18px; }
.step__label { font-family: var(--font-body); font-weight: 800; font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--pink-deep); margin-bottom: 6px; }
.step h3 { font-size: 20px; color: var(--ink); margin-bottom: 8px; }
.step p { font-size: 15px; color: var(--color-text-light); }

.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-top: 30px; }
@media (max-width: 640px) { .stat-row { grid-template-columns: repeat(2, 1fr); } }
.stat { background: var(--color-surface); border-radius: var(--radius); padding: 18px 10px; text-align: center; border-bottom: 4px solid var(--pink); }
.stat__num { font-family: var(--font-display); font-weight: 400; font-size: 27px; color: var(--pink-deep); }
.stat__label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-light); }

.split { display: grid; grid-template-columns: 1.12fr 1fr; gap: 56px; align-items: center; }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; gap: 36px; } }
.split--reverse .split__img { order: -1; }
@media (max-width: 900px) { .split--reverse .split__img { order: 0; } }
.split__img img { border-radius: var(--radius-lg); box-shadow: var(--shadow-md); border-bottom: 6px solid var(--pink); width: 100%; object-fit: cover; }

/* ---------- comparison table (their own us vs them) ---------- */
.compare { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 44px; }
@media (max-width: 760px) { .compare { grid-template-columns: 1fr; } }
.compare__col { border-radius: var(--radius-lg); padding: 30px 28px; border: 1px solid var(--color-border); background: #fff; }
.compare__col--us { border: 2px solid var(--pink); box-shadow: var(--shadow-md); }
.compare__head { font-family: var(--font-display); font-weight: 400; font-size: 19px; margin-bottom: 16px; color: var(--ink); }
.compare__col--us .compare__head { color: var(--pink-deep); }
.compare ul { list-style: none; }
.compare li { display: flex; gap: 11px; padding: 9px 0; font-size: 15.5px; border-top: 1px solid var(--color-border); }
.compare li:first-child { border-top: 0; }
.compare li svg { width: 18px; height: 18px; flex-shrink: 0; margin-top: 3px; }
.compare__col--us li svg { color: var(--pink); }
.compare__col--them { background: var(--color-surface); }
.compare__col--them li { color: var(--color-text-light); }
.compare__col--them li svg { color: #A79EAC; }

/* ---------- dark band with the pitch and the facts card ---------- */
.band { position: relative; background: linear-gradient(140deg, #1A0713, var(--ink) 62%, #12060E); color: #fff; padding: 90px 0 116px; overflow: hidden; }
.band .container { position: relative; z-index: 2; }
.band__grid { display: grid; grid-template-columns: 1.1fr 1fr; gap: 56px; align-items: center; }
@media (max-width: 960px) { .band__grid { grid-template-columns: 1fr; gap: 40px; } }
.band .section-title { color: #fff; }
.band .section-subtitle { color: var(--pink-soft); }
.band p { color: #DCCFD6; }

.form-card { background: #fff; border-radius: var(--radius-lg); padding: 32px 30px; box-shadow: var(--shadow-lg); color: var(--color-text); border-top: 6px solid var(--pink); }
/* The card sits on the dark band, and `.band p` (0,1,1) outranks `.form-card__title`
   (0,1,0), so the card's own headings rendered near-white on white. Scoped rules
   win it back. Caught in the 1440px capture, 2026-09-05. */
.band .form-card, .band .form-card span, .band .form-card li { color: var(--color-text); }
.band .form-card p.form-card__title { color: var(--ink); }
.band .form-card p.form-card__sub, .band .form-card p.form-card__note { color: var(--color-text-light); }
.form-card__title { font-family: var(--font-display); font-weight: 400; font-size: 22px; color: var(--ink); margin-bottom: 6px; }
.form-card__sub { font-size: 14.5px; color: var(--color-text-light); margin-bottom: 20px; }
.form-card__facts { display: grid; gap: 12px; }
.form-card__facts .contact-item { color: var(--color-text); align-items: flex-start; }
.form-card__facts .contact-item svg { color: var(--pink); }
.form-card__facts .contact-item a { color: var(--pink-deep); font-weight: 700; text-decoration: none; }
.form-card__facts .contact-item a:hover { text-decoration: underline; }
.form-card__note { margin-top: 20px; font-size: 14.5px; color: var(--color-text-light); }
.form-card__note a { font-weight: 800; color: var(--pink-deep); text-decoration: none; }
.form-card__note a:hover { text-decoration: underline; }
.contact-item { display: flex; align-items: flex-start; gap: 10px; padding: 5px 0; font-size: 14.5px; }
.contact-item svg { width: 17px; height: 17px; color: var(--pink); flex-shrink: 0; margin-top: 4px; }

/* ---------- lead form: copy scrolls, form column stays put ----------
   The form column is position sticky with align-self start, which is what lets a
   grid item be shorter than its row and therefore able to stick. The top offset
   clears the 84px sticky nav. Below 960px sticky is switched OFF: pinning a tall
   form inside a phone viewport traps the scroll. */
.lead-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 52px; align-items: start; }
.lead-split__copy { max-width: 570px; }
.lead-split__copy > p { color: var(--color-text-light); }
.lead-split__facts { columns: 1; max-width: none; margin-left: 0; margin-right: 0; margin-top: 22px; }
.lead-split__phone { display: inline-block; margin-top: 20px; font-family: var(--font-display); font-weight: 400; font-size: clamp(26px, 3vw, 34px); color: var(--pink-deep); text-decoration: none; }
.lead-split__phone:hover { color: var(--pink); }
.lead-split__phone small { display: block; font-family: var(--font-body); font-size: 12px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--color-text-light); }
.lead-split__phones { display: flex; gap: 34px; flex-wrap: wrap; }
.lead-split__steps { list-style: none; counter-reset: ls; margin-top: 26px; padding-top: 24px; border-top: 1px solid var(--color-border); display: grid; gap: 16px; }
.lead-split__steps li { counter-increment: ls; position: relative; padding-left: 46px; font-size: 15px; color: var(--color-text-light); line-height: 1.6; }
.lead-split__steps li::before { content: counter(ls); position: absolute; left: 0; top: 0; width: 32px; height: 32px; border-radius: 50%; background: var(--pink); color: #fff; font-family: var(--font-display); font-weight: 400; font-size: 15px; display: flex; align-items: center; justify-content: center; }
.lead-split__steps strong { display: block; color: var(--ink); font-size: 16px; }
.lead-split__linkhead { margin-top: 26px; padding-top: 24px; border-top: 1px solid var(--color-border); font-family: var(--font-display); font-weight: 400; font-size: 16px; color: var(--ink); }
.lead-split__links { list-style: none; columns: 2; gap: 24px; margin-top: 12px; }
.lead-split__links li { padding: 6px 0; break-inside: avoid; }
.lead-split__links a { font-size: 15px; font-weight: 700; color: var(--pink-deep); text-decoration: none; }
.lead-split__links a:hover { color: var(--pink); text-decoration: underline; }
@media (max-width: 520px) { .lead-split__links { columns: 1; } }
.lead-split__locs { display: grid; gap: 14px; margin-top: 24px; padding-top: 22px; border-top: 1px solid var(--color-border); }
.lead-split__loc { display: flex; align-items: flex-start; gap: 11px; font-size: 15px; color: var(--color-text-light); }
.lead-split__loc svg { width: 20px; height: 20px; flex-shrink: 0; color: var(--pink); margin-top: 3px; }
.lead-split__loc strong { display: block; color: var(--ink); font-size: 16px; }
.lead-split__loc a { display: inline-block; margin-left: 8px; font-weight: 700; color: var(--pink-deep); text-decoration: none; }
.lead-split__form { position: sticky; top: 100px; align-self: start; }
.lead-split .lead-form { margin: 0; max-width: none; }
@media (max-width: 960px) {
  .lead-split { grid-template-columns: 1fr; gap: 34px; }
  .lead-split__copy { max-width: 660px; margin: 0 auto; }
  .lead-split__form { position: static; top: auto; }
  .lead-split .lead-form { max-width: 660px; margin: 0 auto; }
}

/* ---------- forms ---------- */
.lead-form { background: #fff; border-radius: var(--radius-lg); box-shadow: var(--shadow-md); padding: 34px 30px; border-top: 6px solid var(--pink); }
.lead-form__head { font-family: var(--font-display); font-weight: 400; font-size: 22px; color: var(--ink); margin-bottom: 4px; }
.lead-form__sub { font-size: 14.5px; color: var(--color-text-light); margin-bottom: 20px; }
.lead-form__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.lead-form__full { grid-column: 1 / -1; }
@media (max-width: 640px) { .lead-form__grid { grid-template-columns: 1fr; } .lead-form { padding: 26px 20px; } }
.form-group { display: flex; flex-direction: column; }
.form-label { font-size: 13px; font-weight: 800; margin-bottom: 6px; color: var(--ink); letter-spacing: 0.02em; }
.form-input, .form-textarea, .form-select { width: 100%; padding: 12px 14px; border: 1.5px solid var(--color-border); border-radius: var(--radius); font-family: var(--font-body); font-size: 15.5px; color: var(--color-text); background: #fff; transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease); }
.form-input:focus, .form-textarea:focus, .form-select:focus { outline: none; border-color: var(--pink); box-shadow: 0 0 0 3px var(--pink-wash); }
.form-hint { font-size: 12.5px; color: var(--color-text-light); margin-top: 5px; }
.form-checks { display: grid; gap: 10px; margin-top: 4px; }
.form-check { display: flex; align-items: flex-start; gap: 10px; font-size: 15px; cursor: pointer; padding: 9px 12px; border: 1.5px solid var(--color-border); border-radius: var(--radius); transition: border-color 0.2s var(--ease), background 0.2s var(--ease); }
.form-check:hover { border-color: var(--pink); background: var(--pink-wash); }
.form-check input { margin-top: 4px; accent-color: var(--pink); width: 17px; height: 17px; flex-shrink: 0; }
.form-consent { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; color: var(--color-text-light); line-height: 1.55; cursor: pointer; }
.form-consent input { margin-top: 3px; accent-color: var(--pink); width: 17px; height: 17px; flex-shrink: 0; }
.lead-form__submit { grid-column: 1 / -1; font-family: var(--font-display); font-weight: 400; font-size: 16px; letter-spacing: 0.04em; text-transform: uppercase; background: var(--pink); color: #fff; border: none; border-radius: 999px; padding: 17px 32px; cursor: pointer; box-shadow: 0 6px 18px rgba(224, 1, 112, 0.34); transition: transform 0.25s var(--ease), background 0.25s var(--ease); }
.lead-form__submit:hover { background: var(--pink-mid); transform: translateY(-2px); }
.lead-form__submit:disabled { opacity: 0.65; cursor: default; transform: none; }
.lead-form__result { grid-column: 1 / -1; margin-top: 12px; padding: 12px 14px; border-radius: var(--radius); font-size: 14.5px; font-weight: 600; }
.lead-form__result.is-ok { background: var(--pink-wash); color: var(--pink-deep); }
.lead-form__result.is-err { background: #FDECEC; color: #A11B1B; }
.lead-form__consent { grid-column: 1 / -1; font-size: 11.5px; line-height: 1.55; color: var(--color-text-light); margin-top: 8px; }

/* Anchor jumps must clear the sticky nav (84px) and, on phones, the fixed CTA bar.
   2026-09-05: #estimate now sits on the FORM column, not on the section wrapper.
   On a phone the two columns stack and the copy column is about 1,500px tall, so
   an anchor on the section dropped the visitor two screens above the form. */
#estimate { scroll-margin-top: 100px; }
@media (max-width: 768px) { #estimate { scroll-margin-top: 148px; } }

/* ---------- CTA band ---------- */
.cta-section { position: relative; padding: 94px 0; text-align: center; color: #fff; background-size: cover; background-position: center 42%; overflow: hidden; }
.cta-section::before { content: ''; position: absolute; inset: 0; background: linear-gradient(rgba(10, 10, 10, 0.84), rgba(26, 7, 19, 0.88)); }
.cta-section--flat { background: linear-gradient(135deg, var(--pink) 0%, var(--pink-deep) 100%); }
.cta-section--flat::before { display: none; }
.cta-section .container { position: relative; z-index: 2; }
.cta-section h2 { font-size: clamp(27px, 3.4vw, 43px); margin-bottom: 12px; }
.cta-section p { max-width: 660px; margin: 0 auto 28px; color: rgba(255, 255, 255, 0.92); }
.cta-section--flat .btn--primary { background: var(--ink); box-shadow: none; }
.cta-section--flat .btn--primary:hover { background: #000; }

/* ---------- FAQ ---------- */
.faq-list { max-width: 800px; margin: 40px auto 0; }
.faq-item { border: 1px solid var(--color-border); border-radius: var(--radius); margin-bottom: 10px; overflow: hidden; background: #fff; }
.faq-item__question { width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 12px; text-align: left; padding: 18px 22px; background: none; border: none; cursor: pointer; font-family: var(--font-body); font-weight: 800; font-size: 16px; color: var(--ink); transition: background 0.25s var(--ease); }
.faq-item__question:hover { background: var(--color-surface); }
.faq-item__question svg { flex-shrink: 0; transition: transform 0.3s var(--ease); color: var(--pink); }
.faq-item.active .faq-item__question svg { transform: rotate(180deg); }
.faq-item__answer { max-height: 0; overflow: hidden; transition: max-height 0.4s var(--ease); }
.faq-item.active .faq-item__answer { max-height: 720px; }
.faq-item__answer-inner { padding: 0 22px 20px; color: var(--color-text-light); font-size: 15.5px; }

/* ---------- maps: one per location, full bleed, zero gap ---------- */
.map-section { line-height: 0; display: grid; grid-template-columns: 1fr; }
.map-section--multi { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 1000px) { .map-section--multi { grid-template-columns: 1fr; } }
.map-loc { position: relative; display: flex; flex-direction: column; border-left: 1px solid var(--color-border); }
.map-loc:first-child { border-left: 0; }
@media (max-width: 1000px) { .map-loc { border-left: 0; border-top: 1px solid var(--color-border); } .map-loc:first-child { border-top: 0; } }
.map-loc__label { display: flex; align-items: flex-start; gap: 10px; flex-wrap: wrap; line-height: 1.45; font-size: 14px; color: var(--color-text); background: var(--color-surface); padding: 14px 20px; }
.map-loc__label svg { width: 18px; height: 18px; flex-shrink: 0; color: var(--pink); margin-top: 3px; }
.map-loc__label strong { display: block; font-family: var(--font-display); font-weight: 400; font-size: 15px; color: var(--ink); }
.map-loc__dir { margin-left: auto; font-weight: 800; font-size: 13px; color: var(--pink-deep); white-space: nowrap; text-decoration: none; }
.map-embed { width: 100%; height: 300px; border: 0; display: block; }

/* ---------- hours table ---------- */
.hours-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px; margin-top: 40px; }
@media (max-width: 1000px) { .hours-grid { grid-template-columns: 1fr; } }
.hours-card { background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 26px 24px; box-shadow: var(--shadow-sm); }
.hours-card h3 { font-size: 19px; color: var(--ink); margin-bottom: 4px; }
.hours-card__addr { font-size: 14.5px; color: var(--color-text-light); margin-bottom: 6px; }
.hours-card__phone { display: inline-block; font-weight: 800; color: var(--pink-deep); text-decoration: none; margin-bottom: 14px; }
.hours-card table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
.hours-card th { text-align: left; font-weight: 600; color: var(--color-text-light); padding: 6px 0; border-top: 1px solid var(--color-border); }
.hours-card td { text-align: right; padding: 6px 0; border-top: 1px solid var(--color-border); font-weight: 700; color: var(--ink); }
.hours-card tr:first-child th, .hours-card tr:first-child td { border-top: 0; }
.hours-note { font-size: 13px; color: var(--color-text-light); margin-top: 14px; }

/* ---------- footer ---------- */
.footer { position: relative; background: var(--ink); color: var(--color-on-dark-muted); padding: 82px 0 34px; overflow: hidden; }
.footer .container { position: relative; z-index: 1; }
.footer__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.25fr; gap: 42px; }
@media (max-width: 1024px) { .footer__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .footer__grid { grid-template-columns: 1fr; } }
.footer__logo { background: #fff; display: inline-block; border-radius: 12px; padding: 12px 16px; margin-bottom: 18px; }
.footer__logo img { width: 150px; }
.footer__brand-desc { font-size: 14.5px; margin-bottom: 16px; }
.footer__rating { display: flex; align-items: center; gap: 6px; color: var(--color-google-star); margin-bottom: 18px; }
.footer__rating svg { width: 16px; height: 16px; }
.footer__rating span { color: #fff; font-weight: 700; font-size: 14px; margin-left: 4px; }
.footer__social { display: flex; gap: 12px; flex-wrap: wrap; }
.footer__social a { width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--ink-line); display: flex; align-items: center; justify-content: center; color: var(--color-on-dark-muted); transition: background 0.25s var(--ease), color 0.25s var(--ease); }
.footer__social a:hover { background: var(--pink); color: #fff; border-color: var(--pink); }
.footer__social svg { width: 17px; height: 17px; }
.footer__heading { font-size: 16px; color: #fff; margin-bottom: 16px; }
.footer__links a { display: block; padding: 4px 0; color: var(--color-on-dark-muted); text-decoration: none; font-size: 14.5px; transition: color 0.25s var(--ease); }
.footer__links a:hover { color: var(--pink-soft); }
.footer .contact-item { color: var(--color-on-dark-muted); }
.footer .contact-item a { color: #fff; font-weight: 700; text-decoration: none; }
.footer .contact-item a:hover { color: var(--pink-soft); }
.footer__bottom { margin-top: 46px; padding-top: 24px; border-top: 1px solid var(--ink-line); display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-size: 13.5px; }
.legal-footer { background: #050505; color: #8A7F87; text-align: center; padding: 16px 20px; font-size: 13px; }
.legal-footer a { color: #B7A9B2; text-decoration: none; margin: 0 4px; }
.legal-footer a:hover { color: var(--pink-soft); }

/* ---------- breadcrumbs ---------- */
.breadcrumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; font-size: 13.5px; color: rgba(255, 255, 255, 0.72); }
.breadcrumbs a { color: rgba(255, 255, 255, 0.72); text-decoration: none; }
.breadcrumbs a:hover { color: #fff; }
/* The separator used to be the breadcrumb colour at opacity 0.5, which put the
   "/" at 3.24:1 against the hero on 29 of 33 pages. Opacity is the wrong
   control for this: it dims the glyph against whatever happens to be behind
   it, so the ratio changes page by page with the photograph. The separator is
   part of the reading line, so it now takes the same colour as the rest of the
   breadcrumb and no opacity at all. 2026-09-05. */
.breadcrumbs .sep { color: inherit; opacity: 1; }
.breadcrumbs .current { color: #fff; font-weight: 700; }
/* Breadcrumbs are built for the dark hero. The legal pages and the 404 put them
   on white and used to patch each child with an inline colour, which missed the
   separator, so the slash between Home and the page title was white on white.
   One modifier now covers every child, including any added later. */
.breadcrumbs--light ol,
.breadcrumbs--light a { color: var(--color-text-light); }
.breadcrumbs--light a:hover { color: var(--pink-deep); }
.breadcrumbs--light .sep { color: var(--color-text-light); opacity: 1; }
.breadcrumbs--light .current { color: var(--color-text); }

/* ---------- badge row for light backgrounds (404, legal) ---------- */
.badge-row-light { display: flex; flex-wrap: wrap; justify-content: center; gap: 26px; margin: 0 0 26px; }
.badge-row-light__item { display: inline-flex; align-items: center; gap: 9px; font-size: 15px; color: var(--color-text-light); }
.badge-row-light__item strong { color: var(--ink); }
.badge-row-light__item svg { width: 22px; height: 22px; flex-shrink: 0; }
.badge-row-light__item svg[fill="currentColor"] { color: var(--pink); }

/* ---------- review widget ---------- */
.review-widget { width: 100%; min-height: 640px; border: none; border-radius: 14px; background: #fff; display: block; box-shadow: var(--shadow-sm); }
@media (max-width: 640px) { .review-widget { min-height: 760px; } }

/* ---------- chamber widgets ---------- */
.chambers { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 26px; margin-top: 30px; }
.chambers > div, .chambers > a { max-width: 190px; }
.chambers img { max-height: 90px; width: auto; margin: 0 auto; }

/* ---------- reveal ---------- */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out); }
.reveal.visible { opacity: 1; transform: translateY(0); }
/* No-JS fallback, 2026-09-07. <html> ships with class="no-js" and a one-line inline
   script in <head> swaps it to "js" before the first paint. If that script never runs
   (blocked, broken, or a crawler that does not execute scripts) every .reveal band
   would sit at opacity 0 forever. This rule makes them simply present instead.
   _gate-no-js.js proves it on every page with scripts blocked. */
html.no-js .reveal { opacity: 1; transform: none; }
@keyframes fadeInUp { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: translateY(0); } }
.rbadges { animation: fadeInUp 0.8s var(--ease-out) 0s both; }
.hero__title { animation: fadeInUp 0.8s var(--ease-out) 0.14s both; }
.hero__count { animation: fadeInUp 0.8s var(--ease-out) 0.22s both; }
.hero__text { animation: fadeInUp 0.8s var(--ease-out) 0.3s both; }
.hero__trust { animation: fadeInUp 0.8s var(--ease-out) 0.38s both; }
.hero__actions { animation: fadeInUp 0.8s var(--ease-out) 0.44s both; }
/* The staggered entrance is a desktop nicety. On a phone it was costing about a
   second of Largest Contentful Paint: animation-fill-mode both holds the hero text
   at opacity 0 until its delay has run, and Chrome does not count it as painted
   until it appears. Below 768px the hero is simply there when the page paints.
   design-system.md, Hero Entrance Stagger, 2026-09-07. */
@media (max-width: 767px) {
  .rbadges, .hero__title, .hero__count, .hero__text, .hero__trust, .hero__actions {
    animation: none;
  }
}

@media (max-width: 768px) {
  .section { padding: 64px 0; }
  .band { padding: 64px 0 92px; }
  .cta-section { padding: 66px 0; }
  .hero--home .hero__content { padding: 60px 0 104px; }
  .btn-pair .btn, .hero__actions .btn { width: 100%; text-align: center; }
  /* the chat launcher is fixed bottom right, keep the last tappable thing clear of it */
  .cta-section, .lead-form, .form-card { padding-bottom: 88px; }
  .footer { padding-bottom: 94px; }
}

/* mobile tap targets: 44px floor on anything you tap.
   768 not 767, so the hamburger is still a 44px target at exactly 768px, which
   is where the fixed call bar is still on screen. */
@media (max-width: 768px) {
  .btn, .btn--sm { min-height: 46px; display: inline-flex; align-items: center; justify-content: center; }
  .nav__link, .nav__dropdown-item { min-height: 44px; display: flex; align-items: center; }
  .utility-bar__phone, .breadcrumbs a, .breadcrumbs li { min-height: 44px; display: inline-flex; align-items: center; }
  .nav__hamburger { min-width: 44px; min-height: 44px; }
  .footer__links a { min-height: 44px; display: flex; align-items: center; }
  .check-list li, .lead-split__links li { padding-top: 11px; padding-bottom: 11px; }
  .faq-item__question { min-height: 52px; }
  .form-check { min-height: 48px; align-items: center; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
  .reveal { opacity: 1; transform: none; }
}

/* ============================================================
   PHONE SHAPE, 2026-09-05
   The homepage measured 23,677px on a 390px phone, 29 screens. The
   reference estate of 13 live homepages runs 5,828 to 11,523 with a
   median of 8,524, section padding 48px at phone width, and nothing
   taller than about 2,200 in one band. _gate-mobile-shape.js holds
   those numbers and _qa.js cannot pass while it fails.

   Nothing leaves the DOM. Secondary copy sits inside <details class="more">
   which ships OPEN in the HTML (so a crawler reads every word) and is
   closed by one inline script on phones only. On wide screens the
   summary row is hidden and every block reads exactly as before.
   ============================================================ */

/* ---------- disclosure rows ---------- */
details.more > summary {
  list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  min-height: 48px; padding: 10px 2px; margin: 14px 0 0; cursor: pointer;
  font-family: var(--font-body); font-weight: 800; font-size: 15px; letter-spacing: 0.02em; color: var(--pink-deep);
  border-top: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border);
  -webkit-tap-highlight-color: transparent;
}
details.more > summary::-webkit-details-marker { display: none; }
details.more > summary::after {
  content: ''; flex-shrink: 0; width: 9px; height: 9px; margin: 0 6px 4px 0;
  border-right: 2.5px solid currentColor; border-bottom: 2.5px solid currentColor;
  transform: rotate(45deg); transition: transform 0.25s var(--ease);
}
details.more[open] > summary::after { transform: rotate(-135deg); margin: 4px 6px 0 0; }
details.more[open] > summary { margin-bottom: 14px; }
details.more--dark > summary { color: var(--pink-soft); border-color: rgba(255, 255, 255, 0.18); }
details.more--step > summary { margin-top: 0; }
details.more--map > summary { line-height: 1.4; font-size: 14px; margin: 0; padding: 8px 20px; border-top: 0; border-bottom: 0; background: var(--color-surface); min-height: 44px; }
details.more--map[open] > summary { margin-bottom: 0; }
@media (min-width: 768px) { details.more > summary { display: none; } }

/* ---------- the lead band: heading and first paragraph, the form, then the folded copy.
   On a desktop the form column spans both rows so the two column layout is unchanged. */
.lead-split { row-gap: 0; }
.lead-split__form { grid-column: 2; grid-row: 1 / span 2; }
.lead-split__more { grid-column: 1; grid-row: 2; }
.lead-form__csz { display: grid; grid-template-columns: 1.4fr 1fr 0.9fr; gap: 16px; }
@media (max-width: 960px) {
  .lead-split { row-gap: 26px; }
  .lead-split__form, .lead-split__more { grid-column: auto; grid-row: auto; }
  .lead-split__more { max-width: 660px; margin: 0 auto; width: 100%; }
  /* stacked, the card sits right under the section heading that says the same words */
  .lead-form__head { display: none; }
}
@media (max-width: 640px) {
  .lead-form__grid { grid-template-columns: 1fr 1fr; gap: 12px; }
  .lead-form__csz { gap: 12px; }
  .lead-form { padding: 22px 18px 88px; }
}
@media (max-width: 480px) {
  .form-checks { grid-template-columns: repeat(3, 1fr); gap: 8px; }
  .form-check { padding: 8px 8px; gap: 7px; font-size: 13.5px; line-height: 1.25; min-height: 48px; }
  .form-check input { margin-top: 0; }
  .form-textarea { min-height: 96px; }
}

/* ---------- phone padding ladder: 48 at phone width, 64 at 768, 92 wide ---------- */
@media (max-width: 767px) {
  .duck-ghost { display: none; }   /* a 180px watermark is a lot of a 390px screen */
}
@media (max-width: 480px) {
  .section { padding: 48px 0; }
  .band { padding: 48px 0 68px; }
  .cta-section { padding: 48px 0 88px; }
  .footer { padding-top: 48px; }
  .hero--home .hero__content { padding: 44px 0 92px; }
  .card-grid, .step-grid, .compare, .area-grid, .faq-list, .section__footer { margin-top: 28px; }
  .card-grid { gap: 14px; }
  .section-title { margin-bottom: 14px; }
  .trust-strip__card { gap: 12px; padding: 18px 20px; }
  .creds { padding: 20px 0; }
  .creds__row { gap: 8px 18px; }
  .creds__badges { gap: 16px; margin-top: 14px; }
  .creds__badges img { height: 40px; }
  .split { gap: 22px; }
  .split__img img { max-height: 240px; object-fit: cover; object-position: center 30%; }
  .svc-card__media { aspect-ratio: 2 / 1; }
  .svc-card__body { padding: 18px 18px 20px; }
  .svc-card h3 { font-size: 19px; }
  .svc-card p { font-size: 15px; margin-bottom: 14px; }
  .step { padding: 22px 20px; }
  .step__num { width: 46px; height: 46px; font-size: 20px; margin-bottom: 12px; }
  .compare__col { padding: 22px 20px; }
  .stat-row { margin-top: 22px; }
  .btn-pair { gap: 10px; }
}

/* ---------- four proof cards: two up on a phone ---------- */
@media (max-width: 700px) {
  .card-grid--4 { grid-template-columns: 1fr 1fr; gap: 12px; }
  .card-grid--4 .icon-card { padding: 20px 16px; }
  .card-grid--4 .icon-card__icon { width: 42px; height: 42px; margin-bottom: 12px; }
  .card-grid--4 .icon-card__icon svg { width: 21px; height: 21px; }
  .card-grid--4 .icon-card h3 { font-size: 16px; line-height: 1.25; }
  .card-grid--4 .icon-card p { font-size: 14px; }
}

/* ---------- testimonials: a swipe row on a phone, every card still in the DOM ---------- */
@media (max-width: 700px) {
  .reviews-row { display: flex; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; gap: 12px; margin: 28px -24px 0; padding: 6px 24px 14px; scrollbar-width: none; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; }
  .reviews-row::-webkit-scrollbar { display: none; }
  .reviews-row > .review-card { flex: 0 0 82%; scroll-snap-align: start; scroll-margin-left: 24px; padding: 22px 20px; }
  .reviews__cta { margin-top: 20px; }
}

/* ---------- service area: two up at phone width, every service link visible ----------
   The fourteen cards come as two grids, six then eight, the second one folded behind a
   details.more row on a phone. At every width the second grid sits one grid-gap below
   the first so on a wide screen (summary hidden, details open) the rows are exactly
   where one grid of fourteen put them. The three service links stack under the town
   name at <= 480px, each on its own line, so nothing wraps mid-word in a 160px card;
   the decorative bullet between them and the pin icon are hidden there, which is why
   Western Springs fits on one line. Nothing is display:none but decoration. */
.area-grid--more { margin-top: 16px; }
details.more--areas[open] > summary { margin-bottom: 10px; }
@media (max-width: 560px) {
  .area-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
  .area-grid--more { margin-top: 10px; }
  .area-card { padding: 12px 12px; }
  .area-card__city { font-size: 15px; margin-bottom: 4px; }
}
@media (max-width: 480px) {
  /* Archivo Black sets Western Springs at 126px wide at 14px; with 10px side padding the card
     offers 146/139/131px at 390/375/360, so every town name holds one line */
  .area-card { padding: 12px 10px; }
  .area-card__city { font-size: 14px; margin-bottom: 2px; min-height: 28px; }
  .area-card__city svg { display: none; }
  .area-card__links { flex-direction: column; gap: 0; font-size: 13px; }
  .area-card__links > span { display: none; }
  .area-card__links a { display: block; padding: 2px 0; min-height: 24px; }
}
@media (max-width: 380px) { .area-card__city { font-size: 13.5px; } }
@media (max-width: 340px) { .area-grid { grid-template-columns: 1fr; } }

/* ---------- footer: link columns two up ---------- */
@media (max-width: 640px) {
  .footer__grid { gap: 30px; }
  .footer__links { display: grid; grid-template-columns: 1fr 1fr; column-gap: 14px; }
  .footer__bottom { margin-top: 30px; }
}
details.more > p { margin-bottom: 16px; }

/* ---------- second pass ---------- */
/* footer columns: the heading is the tappable row on a phone; on wide screens the
   summary renders as a plain block so the column is exactly what it was */
details.more--footer > summary { margin: 0; padding: 0; border: 0; min-height: 44px; color: #fff; }
details.more--footer > summary .footer__heading { margin: 0; }
details.more--footer > summary::after { color: var(--pink-soft); }
details.more--footer[open] > summary { margin-bottom: 12px; }
@media (min-width: 768px) {
  details.more--footer > summary { display: block; pointer-events: none; min-height: 0; }
  details.more--footer > summary::after { display: none; }
  details.more--footer > summary .footer__heading { margin-bottom: 16px; }
}

/* services: a swipe row on a phone, every card still in the DOM */
@media (max-width: 700px) {
  .services-row { display: flex; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; gap: 12px; margin: 28px -24px 0; padding: 6px 24px 14px; scrollbar-width: none; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; }
  .services-row::-webkit-scrollbar { display: none; }
  .services-row > .svc-card { flex: 0 0 84%; scroll-snap-align: start; scroll-margin-left: 24px; }
}

@media (max-width: 480px) {
  .hero--home .hero__content { padding: 40px 0 84px; }
  .creds__row { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 10px; justify-items: start; }
  .creds__pill { font-size: 11.5px; letter-spacing: 0.03em; gap: 6px; }
  .creds__badges { gap: 12px; margin-top: 14px; }
  .creds__badges img { height: 36px; }
  .card-grid--4 .icon-card { padding: 16px 14px; }
  .card-grid--4 .icon-card p { font-size: 13.5px; }
  .split__img img { max-height: 200px; }
  .faq-item { margin-bottom: 6px; }
  .map-loc__label { padding: 10px 20px; }
  .lead-form__grid { gap: 10px; }
  .form-textarea { height: 96px; }
  .lead-form__consent { margin-top: 6px; }
}

/* ---------- third pass: trims ---------- */
@media (max-width: 480px) {
  /* the tagline row of the utility bar says what the hero trust row says 300px below it */
  .utility-bar .container > .utility-bar__item { display: none; }
  .hero--home .hero__content { padding: 36px 0 72px; }
  .hero__trust { gap: 6px 18px; margin-bottom: 22px; }
  .area-card { padding: 8px 12px; }
  .area-card__city { min-height: 32px; }
  .reviews__cta { gap: 8px; flex-wrap: nowrap; }
  .reviews__cta .btn { flex: 1 1 0; padding: 10px 8px; font-size: 11.5px; letter-spacing: 0.03em; line-height: 1.2; min-height: 46px; text-align: center; }
  .review-card__text { font-size: 15px; }
  .split__img img { max-height: 160px; }
  .form-input, .form-textarea, .form-select { padding: 10px 12px; }
  .form-label { margin-bottom: 4px; }
  .lead-form__grid { gap: 8px; }
  .lead-form { padding: 18px 16px 64px; }
  .cta-section { padding-bottom: 64px; }
  .map-embed { height: 240px; }
  .map-loc__label { padding: 8px 20px; }
  .faq-item__question { padding: 14px 18px; }
  .footer__logo img { width: 120px; }
  .footer__logo { padding: 10px 14px; margin-bottom: 14px; }
}

/* ---------- fourth pass: polish ---------- */
@media (max-width: 767px) {
  details.more:not(.more--map):not(.more--footer) > summary { margin-top: 10px; }
  /* the three step rows read as one list: no gap, one rule between rows */
  .step-grid { gap: 0; }
  details.more--step > summary { margin-top: 0; }
  details.more--step + details.more--step > summary { border-top: 0; }
  details.more--step[open] + details.more--step > summary { border-top: 1px solid var(--color-border); }
}
@media (max-width: 480px) {
  .band { padding-bottom: 56px; }
  .trust-strip__card { gap: 10px; padding: 16px 20px; }
  .reviews-row, .services-row { padding-bottom: 10px; }
}
@media (max-width: 960px) {
  .lead-split { row-gap: 18px; }
}

@media (max-width: 480px) {
  .section-title--underline { padding-bottom: 14px; }
  .section-subtitle { margin-bottom: 8px; }
  .lead-form { padding-bottom: 48px; }
}

/* ---------- fifth pass: measured with the real faces ----------
   2026-09-05, later. The shape gate now loads Barlow and Archivo Black before
   it measures, and the real faces wrap more lines than the fallbacks did, so
   the page that passed at 11,5xx measured 12,114. Nothing leaves the DOM here
   either. The body sets at the 16px the design brief names (the wide screen
   keeps 17), reading copy tightens from 1.68 to 1.6, the bands that carried
   extra bottom room lose it, the footer columns sit closer, and the pitch
   paragraph of the dark band folds behind a row on a phone. */
@media (max-width: 767px) {
  body { font-size: 16px; line-height: 1.6; }
  .icon-card p, .svc-card p, .step p, .compare li, .check-list li span,
  .faq-item__answer-inner, .lead-split__copy > p, .review-card__text { line-height: 1.5; }
  details.more--pitch > summary { margin-top: 0; }
  details.more--pitch[open] > summary { margin-bottom: 10px; }
}
/* the lead band's intro paragraph now sits inside the folded block, ahead of the
   facts list. On a wide screen it used to be a grid row of its own, so its 16px
   bottom margin and the list's 22px top margin both counted; as siblings they
   collapse to 22. This puts the 16 back so the section measures what it did. */
@media (min-width: 768px) {
  .lead-split__copy--more > p + .lead-split__facts { margin-top: 38px; }
}
@media (max-width: 480px) {
  .band { padding-bottom: 48px; }
  .cta-section { padding-bottom: 48px; }
  .footer { padding-bottom: 48px; }
  .footer__grid { gap: 14px; }
  .footer__brand-desc { margin-bottom: 12px; }
  .footer__rating { margin-bottom: 14px; }
  .footer__bottom { margin-top: 22px; padding-top: 18px; }
  .lead-form { padding-bottom: 24px; }
  .map-embed { height: 220px; }
  .review-card__text { font-size: 14.5px; }
  .split { gap: 18px; }
  .split__img img { max-height: 150px; }
  .section__footer { margin-top: 22px; }
  .section__footer p { font-size: 15px; }
  .card-grid--4 .icon-card { padding: 14px 14px 16px; }
  .card-grid--4 .icon-card__icon { margin-bottom: 10px; }
  .faq-item { margin-bottom: 4px; }
}
