/* Wild Bunch LLC — one-page site
   Palette and type are taken from the client's own logo: a glowing electric-blue crest
   (a raccoon roofline mark and a wolf-in-a-cowboy-hat badge) lit periwinkle-indigo on
   deep indigo. Two web fonts carry the hand-lettered voice of that badge (Permanent
   Marker for display, Rock Salt for eyebrows); both load with font-display:swap so a
   slow font never blocks the first paint. */

/* Self-hosted so the page does not have to reach two extra origins before it can
   style any text -- see tools/build-logos.py's sibling note on rural mobile.
   Both faces are Apache 2.0. Latin subset only, as shipped by Google Fonts. */

@font-face {
  font-family: 'Permanent Marker';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/permanent-marker-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Rock Salt';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/rock-salt-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --navy: #10142e;        /* primary dark ground */
  --navy-deep: #0a0d20;   /* deeper panel — matches the logo's ground */
  --navy-darkest: #060818;

  --ice: #eef0fb;         /* light ground + light text on dark */
  --ice-soft: #f5f6fd;    /* slightly cooler light ground */
  --rule: #d8dcf2;        /* hairline on light grounds */

  --ink: #141631;
  --ink-mid: #3a3f63;
  --ink-soft: #61678f;    /* ~4.5:1 on --ice, so it is safe for normal-size body copy */

  --mist: #c3cbe9;        /* body text on dark */
  --mist-bright: #dde2f6;
  --mist-dim: #9aa3cf;
  --mist-faint: #6b74a8;  /* fineprint on dark */
  --slate: #3a4691;       /* structural blue: chat bubble, illustration strokes */

  --sky: #93a7f2;         /* accent text and rules on dark */
  --blue-bright: #2c3a8c; /* the logo indigo — accent on light grounds, never behind white text */
  --blue: #2c3a8c;        /* CTA fill, white text: ~11:1 */
  --blue-dark: #1e2a6b;   /* CTA hover */

  --wrap: 1180px;
  --display: "Permanent Marker", "Segoe Print", cursive;
  --script: "Rock Salt", "Segoe Script", cursive;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--navy);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

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

h1, h2, h3 { font-weight: 400; line-height: 1.1; margin: 0; }
h1, h2 { font-family: var(--display); letter-spacing: 0; }
h1 { font-size: clamp(44px, 6vw, 76px); line-height: 1.02; letter-spacing: -.01em; }
h2 { font-size: clamp(30px, 3.8vw, 46px); text-wrap: balance; }
h3 { font-size: 20px; font-weight: 600; }
p { margin: 0 0 1em; }
a { color: var(--blue); }
a:hover { color: var(--blue-dark); }

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

.sr-only, .skip-link {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link:focus {
  position: fixed; left: 8px; top: 8px; z-index: 300;
  width: auto; height: auto; clip: auto; margin: 0;
  background: var(--blue); color: #fff; padding: 12px 18px; text-decoration: none;
}

.wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: 24px; }
.wrap.narrow { max-width: 960px; }
.center { text-align: center; }
.mb-md { margin-bottom: 40px; }
.mb-lg { margin-bottom: 56px; }

/* The header and its jump nav are both sticky, so anchored sections have to clear
   them when the browser scrolls to an id. */
main section[id], .panel[id] { scroll-margin-top: 132px; }

/* The crest is a raster PNG (a wolf-in-a-cowboy-hat badge for the hero, a raccoon
   roofline mark for the header/footer). Each ships with its own soft glow that fades
   to transparency, so it drops onto the dark grounds without a visible box. */
.logo { flex: none; }
/* The logos sit inside <picture> so a WebP can be offered ahead of the PNG.
   <picture> is an inline wrapper, which would otherwise introduce a baseline
   gap under the crest and break the header's flex alignment. */
.logo-wrap { display: flex; flex: none; }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: inherit; font-weight: 700; font-size: 17px; line-height: 1;
  padding: 15px 26px; border-radius: 6px; border: 1px solid transparent;
  text-decoration: none; cursor: pointer; min-height: 48px;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.btn-primary { background: var(--blue); color: #fff; }
.btn-primary:hover { background: var(--blue-dark); color: #fff; }
.btn-outline { background: transparent; color: var(--ice); border-color: rgba(238, 240, 251, .35); font-weight: 600; }
.btn-outline:hover { background: rgba(238, 240, 251, .07); border-color: var(--ice); color: var(--ice); }
.btn-dark { background: var(--navy); color: var(--ice); }
.btn-dark:hover { background: var(--navy-deep); color: var(--ice); }
.btn-sm { font-size: 16px; padding: 12px 20px; min-height: 44px; }
.btn-lg { font-size: 18px; padding: 16px 28px; min-height: 52px; }
.ico { flex: none; }

/* ---------- emergency banner + header ---------- */

.emergency-banner {
  background: var(--blue); color: #fff; text-align: center;
  padding: 10px 16px; font-size: 15px; font-weight: 600; letter-spacing: .01em;
}
/* Vertical padding on an inline link grows the touch area without changing the
   line box, so the banner keeps its height. */
.emergency-banner a { color: #fff; text-underline-offset: 3px; padding: 13px 4px; }

.site-header {
  background: var(--navy); border-bottom: 1px solid rgba(238, 240, 251, .12);
  position: sticky; top: 0; z-index: 50;
}
.header-inner { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding-block: 14px; }
.brand { display: inline-flex; align-items: center; gap: 14px; text-decoration: none; min-height: 44px; }
.brand-mark { width: 58px; height: 58px; object-fit: contain; }
.brand-name { font-family: var(--display); font-size: 22px; letter-spacing: .02em; color: var(--ice); line-height: 1; }
.brand-sub { display: block; font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: var(--mist-dim); margin-top: 4px; }
.header-right { display: flex; align-items: center; gap: 10px; }
.header-area { color: var(--mist-dim); font-size: 14px; margin-right: 10px; }
.header-right .btn-label { display: none; }

/* ---------- jump nav ---------- */

/* This row used to scroll sideways, which hid whatever did not fit -- on a phone
   that was most of it. Now that the services live in one disclosure the row is
   short enough to wrap instead, so nothing is ever off-screen. Wrapping also
   means the nav can no longer be an overflow container, which is what lets the
   dropdown panel below hang outside it without being clipped. */
.jumpnav { border-top: 1px solid rgba(238, 240, 251, .1); }
.jumpnav-inner { display: flex; flex-wrap: wrap; align-items: center; gap: 0 6px; }
.jumpnav a, .navdrop > summary {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px;
  color: var(--mist-dim); text-decoration: none; font-size: 14.5px; font-weight: 600;
  border-bottom: 2px solid transparent; white-space: nowrap;
}
.jumpnav a:hover, .navdrop > summary:hover { color: var(--ice); }
.jumpnav a.is-current { color: var(--sky); border-bottom-color: var(--sky); }

/* ---------- services dropdown ---------- */

/* <details> rather than a scripted menu: the links are in the markup whether or
   not the panel is open, so crawlers and no-JS visitors see the full set. */
/* display:flex, not block: the summary is inline-flex like the sibling links, and
   inside a block <details> it would sit on a text baseline and pick up ~6px of
   leading above it, leaving "Services" riding higher than everything else. */
.navdrop { position: relative; display: flex; align-items: stretch; }
.navdrop > summary { cursor: pointer; gap: 6px; list-style: none; -webkit-user-select: none; user-select: none; }
.navdrop > summary::-webkit-details-marker { display: none; }
.navdrop > summary::after {
  content: ""; width: 6px; height: 6px; margin-top: -3px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); transition: transform .15s ease;
}
.navdrop[open] > summary::after { margin-top: 3px; transform: rotate(-135deg); }
.navdrop.is-current > summary { color: var(--sky); border-bottom-color: var(--sky); }

.navdrop-menu {
  position: absolute; top: 100%; left: 0; z-index: 60;
  display: flex; flex-direction: column; padding: 6px;
  /* The panel is positioned against the summary, so on a narrow screen the
     min-width has to yield to the viewport or it runs off the right edge. */
  min-width: min(244px, calc(100vw - 24px));
  background: var(--navy); border: 1px solid rgba(238, 240, 251, .16);
  border-radius: 10px; box-shadow: 0 18px 44px rgba(0, 0, 0, .5);
}
.jumpnav .navdrop-menu a {
  min-height: 0; padding: 11px 12px; border-bottom: 0; border-radius: 7px;
}
.jumpnav .navdrop-menu a:hover { background: rgba(238, 240, 251, .09); color: var(--ice); }
.jumpnav .navdrop-menu a.is-current { color: var(--sky); background: rgba(125, 187, 232, .1); }

/* The row wraps rather than scrolls, so on a phone it buys back its width in
   padding instead of in hidden items. */
@media (max-width: 560px) {
  /* The 24px .wrap gutter is right for prose and too wide for a nav bar. Pulling
     it back to 10px is what gets all five items onto one row at 375px, which
     matters more than usual here because the header is sticky -- a second row
     would cost 44px of screen for the whole session, not just at the top. */
  .jumpnav-inner { gap: 0; padding-left: 10px; padding-right: 10px; }
  .jumpnav a, .navdrop > summary { padding: 0 7px; font-size: 13.5px; }
  .navdrop-menu { left: -10px; }
}

/* ---------- hero ---------- */

/* The illustrated scene that used to sit on the right was cut at the client's request
   — it read as decoration rather than as the work — and for a while the copy was left
   centred on its own. On a wide screen that read as a narrow column adrift in the
   middle of the page, inset from the header above it and using about 40% of the width.

   So the crest takes the empty half back. From 1000px up the two sit side by side in
   the same .wrap the header uses, which lines the hero up with everything above it.
   The crest also stops being the compromise it was: stacked above the copy it had to
   shrink to 300px to keep both CTAs on the first screen, and beside it there is no
   such trade. Below 1000px it stacks and re-centres, which is the phone layout. */
.hero { background: var(--navy); }
.hero-inner {
  display: flex; flex-direction: column; align-items: center;
  padding-block: clamp(40px, 5vw, 64px);
}
.hero-figure { width: min(300px, 72%); margin: 0 0 18px; }
.hero-logo {
  width: 100%; height: auto;
  filter: drop-shadow(0 18px 44px rgba(120, 150, 255, .35));
}
.hero-copy {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  max-width: 660px; width: 100%;
}
.hero-copy .lede, .hero-copy h1 { margin-inline: auto; }

@media (min-width: 1000px) {
  .hero-inner {
    flex-direction: row; align-items: center; justify-content: center;
    gap: clamp(40px, 5vw, 80px);
  }
  .hero-figure { flex: none; width: min(440px, 40%); margin: 0; }
  .hero-copy { align-items: flex-start; text-align: left; max-width: 620px; }
  /* The column is a flex container, so auto inline margins would still centre these
     inside it even with align-items:flex-start. */
  .hero-copy .lede, .hero-copy h1 { margin-inline: 0; }
  .hero-actions { justify-content: flex-start; }
}
.eyebrow {
  margin: 0 0 20px; font-family: var(--script); font-size: 13px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--sky); font-weight: 400;
}
.hero h1 { color: var(--ice); text-wrap: balance; }
.hero h1 em { font-style: italic; color: var(--sky); }
.hero .lede { margin: 20px 0 0; font-size: 19px; line-height: 1.6; color: var(--mist); max-width: 52ch; text-wrap: pretty; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 26px; justify-content: center; }
.hero-secondary { margin: 20px 0 0; }
.link-strong {
  color: var(--sky); font-weight: 700; font-size: 18px;
  text-underline-offset: 4px; display: inline-flex; align-items: center; min-height: 44px;
}
.link-strong:hover { color: var(--ice); }
/* The inspection's value, restated wherever a CTA appears — nobody should have to
   reach the FAQ to find out what $200 buys. */
.hero-value, .cta-value { font-size: 14.5px; color: var(--mist-dim); margin: 4px 0 0; }
.section-cream .cta-value, .section-paper .cta-value { color: var(--ink-soft); }
.hero-species { margin: 22px 0 0; font-size: 14px; letter-spacing: .06em; color: var(--mist-dim); }

/* ---------- trust bar ---------- */

.trustbar {
  background: var(--navy-deep);
  border-block: 1px solid rgba(238, 240, 251, .08);
}
.trust-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 18px; padding-block: 22px;
}
.trust { display: flex; flex-direction: column; gap: 4px; }
.trust-key { font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--sky); font-weight: 700; }
.trust-val { color: var(--mist-bright); font-size: 15px; line-height: 1.4; }

/* ---------- service-area qualifier strip ---------- */

.areastrip { background: var(--ice); border-bottom: 1px solid var(--rule); }
.areastrip-inner {
  display: flex; flex-wrap: wrap; align-items: center; gap: 16px 28px; padding-block: 22px;
}
.areastrip-copy h2 { font-family: var(--sans); font-size: 19px; font-weight: 700; color: var(--ink); line-height: 1.3; }
.areastrip-copy p { margin: 4px 0 0; font-size: 15px; color: var(--ink-soft); }

.area-check { display: flex; gap: 10px; flex-wrap: wrap; }
.area-check input {
  flex: 1 1 190px; min-width: 0; min-height: 48px; padding: 12px 14px;
  font-size: 16px; font-family: inherit; color: var(--ink);
  background: #fff; border: 1px solid var(--rule); border-radius: 6px;
}
.area-check input:focus { border-color: var(--blue); }
.area-check-lg { max-width: 440px; margin-top: 26px; }
.area-result {
  flex-basis: 100%; margin: 0; font-size: 15.5px; line-height: 1.6; color: var(--ink);
  background: var(--ice-soft); border: 1px solid var(--rule); border-left: 3px solid var(--blue);
  border-radius: 6px; padding: 12px 16px; max-width: 620px;
}
.area-result a { font-weight: 700; }
.area-check-lg + .area-result { margin-top: 16px; }

/* ---------- "what are you hearing?" chips ---------- */

.chip-head {
  font-family: var(--script); font-weight: 400; font-size: 12px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--blue-dark); margin: 36px 0 14px;
}
.chips { display: flex; flex-wrap: wrap; gap: 10px; }
.chip {
  display: inline-flex; align-items: center; min-height: 48px; padding: 10px 18px;
  font: inherit; font-size: 15.5px; font-weight: 600; color: var(--ink);
  background: #fff; border: 1px solid var(--rule); border-radius: 999px;
  cursor: pointer; text-align: left; line-height: 1.25;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.chip:hover { border-color: var(--blue); color: var(--blue-dark); }
.chip[aria-expanded="true"] { background: var(--blue); border-color: var(--blue); color: #fff; }

.panels { margin-top: 28px; display: grid; gap: 16px; }
.panels[data-collapsed] { display: block; margin-top: 0; }
.panels[data-collapsed] .panel { display: none; margin-top: 24px; }
.panels[data-collapsed] .panel.is-open { display: block; }
.panel {
  background: #fff; border: 1px solid var(--rule); border-left: 3px solid var(--blue);
  border-radius: 8px; padding: 22px 24px;
}
.panel h3 { margin-bottom: 8px; color: var(--ink); }
.panel p { margin: 0; font-size: 16px; }

.panel-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 32px; }
.panel-cta .cta-value { flex-basis: 100%; margin: 0; }

/* ---------- section grounds ---------- */

.section { padding-block: clamp(64px, 8vw, 96px); }
.section-cream { background: var(--ice); }
.section-paper { background: var(--ice-soft); }
.section-forest { background: var(--navy); }
.section-deep { background: var(--navy-deep); }
.bordered-top { border-top: 1px solid var(--rule); }

.section-cream, .section-paper { color: var(--ink); }
.section-cream h2, .section-paper h2, .section-cream h3, .section-paper h3 { color: var(--ink); }
.section-cream p, .section-paper p { color: var(--ink-mid); max-width: 62ch; }
.section-forest, .section-deep { color: var(--mist); }
.section-forest h2, .section-deep h2, .section-forest h3, .section-deep h3 { color: var(--ice); }
.section-forest p, .section-deep p { color: var(--mist); }

.section-title-lg { font-size: clamp(32px, 4.2vw, 52px); line-height: 1.05; max-width: 20ch; }
.section-title-xl { font-size: clamp(34px, 4.6vw, 56px); line-height: 1.05; }
.section-sub { color: var(--ink-soft); font-size: 17px; }
.section-deep .section-sub, .section-forest .section-sub { color: var(--mist-dim); }
.muted { color: var(--ink-soft); }
.fineprint { font-size: 13px; color: var(--mist-faint); margin: 16px 0 0; }
.section-cream .fineprint, .section-paper .fineprint { color: var(--ink-soft); }

.split { display: grid; gap: 64px; align-items: center; }
.split-wide-left { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); }
.split-wide-right { grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr); }
.section-forest .split { align-items: start; margin-top: 48px; }

/* ---------- photos ---------- */

.photo { margin: 0; }
.photo img { width: 100%; height: auto; border-radius: 8px; }
.photo figcaption { font-size: 13px; line-height: 1.5; margin-top: 10px; color: var(--mist-dim); }
.section-cream .photo figcaption, .section-paper .photo figcaption { color: var(--ink-soft); letter-spacing: .02em; }
.photo-raised img { box-shadow: 0 24px 48px -24px rgba(7, 9, 26, .45); }
.photo-offset { padding-top: 34px; }

/* A single wildlife photo dropped into a prose column. Constrained rather than
   full-width: at 960px the .wrap.narrow measure is already at the top of what is
   comfortable to read, and a photo running the full width of it reads as a banner
   interrupting the argument rather than an illustration supporting it. */
.species-photo { max-width: 520px; margin: 34px 0 0; }

.door-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

/* Two of the three photos are self-contained before/after composites, so they are
   never cropped: a 4:3 cover crop would cut the "before" straight off and destroy
   the comparison the photo exists to make. A square box with `contain` gives the
   grid a tidy shared height and letterboxes the one portrait shot against the
   section's own background, which reads as intentional on a dark ground. */
.gallery {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 22px; margin-top: 40px; align-items: start;
}
.gallery img { aspect-ratio: 1 / 1; object-fit: contain; }

/* The gallery page mixes square before/after composites with portrait phone photos.
   A grid would either crop them to a common ratio or leave the short ones sitting in
   tall ragged rows, and cropping a before/after composite destroys the thing it is
   showing. Columns give a masonry flow instead: every photo keeps its own shape and
   the packing stays tight. Reading order runs down each column rather than across,
   which is the trade, and for photographs grouped by theme it costs nothing. */
.gallery-grid { columns: 3 280px; column-gap: 22px; margin-top: 40px; }
.gallery-grid > .photo { break-inside: avoid; margin: 0 0 22px; display: inline-block; width: 100%; }
.gallery-grid img { width: 100%; height: auto; display: block; }

/* Route out of the homepage teaser into the full set. */
.work-more { margin: 34px 0 0; text-align: center; }

/* Credit line for any photograph that is not the client's own work. The site's
   claim is scoped rather than absolute -- "every repair photo is our own job, and
   anything that isn't says so underneath" -- and this is the "says so underneath".
   Quiet, but never hidden: it sits in the flow under the caption at a readable
   size, because a disclosure nobody can read is not a disclosure. */
.photo-credit {
  display: block; margin-top: 6px;
  font-size: 12.5px; line-height: 1.45; color: var(--mist-dim);
  letter-spacing: .01em;
}
.photo-credit a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.photo-credit a:hover { color: var(--ice); }
.section-cream .photo-credit, .section-paper .photo-credit { color: var(--ink-soft); }
.section-cream .photo-credit a:hover, .section-paper .photo-credit a:hover { color: var(--ink); }

/* ---------- problem callout ---------- */

.callout-card {
  background: var(--navy); border-radius: 8px; padding: 26px 28px; margin: 28px 0;
}
.callout-card p { margin: 0; color: var(--mist-bright); max-width: none; }
.callout-card strong { color: var(--sky); }

.emphasis { border-left: 3px solid var(--sky); padding-left: 18px; }
.section-forest .emphasis { color: var(--ice); }
.section-forest .emphasis + .btn { margin-top: 8px; }

/* ---------- meet the owner ---------- */

.eyebrow-dark { color: var(--blue-dark); }
/* One column while there is no photograph of Mike to sit beside the copy — a
   half-width text block with nothing opposite it just reads as a missing image. */
.owner-single { max-width: 820px; }
#owner h2 { margin-bottom: 22px; }
.cert {
  margin: 30px 0 0; display: flex; gap: 18px; align-items: flex-start;
  background: var(--ice-soft); border: 1px solid var(--rule); border-radius: 10px; padding: 18px;
}
/* <picture> is the flex item here, so it needs the sizing — an img inside it is
   capped by max-width:100% of whatever the flex row leaves the picture. */
.cert picture { flex: none; width: 170px; }
.cert img { width: 100%; height: auto; border-radius: 6px; border: 1px solid var(--rule); }
.cert figcaption { font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); }
.owner-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

/* ---------- inspection ---------- */

/* The section used to lead with a "$200" feature block. Wild Bunch no longer
   advertises a figure -- some inspections are complimentary as part of a larger
   exclusion or repair project, the rest are quoted per job -- so the price
   components were removed and the fee statement now uses .callout-card. */

.includes { list-style: none; margin: 32px 0 0; padding: 0; }
.includes li {
  position: relative; padding: 14px 8px 14px 34px; border-bottom: 1px solid var(--rule);
  color: var(--ink-mid); font-size: 16.5px; line-height: 1.6;
}
.includes li::before {
  content: ""; position: absolute; left: 6px; top: 22px;
  width: 12px; height: 7px; border-left: 2.5px solid var(--blue); border-bottom: 2.5px solid var(--blue);
  transform: rotate(-45deg);
}
/* Fee caveats under the inspection list (access surcharge, quoting). */
.price-note { font-size: 15.5px; margin: 32px auto 0; }
.inspection-cta { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 36px; }
#inspection .cta-value { margin-top: 12px; }

/* ---------- steps ---------- */

.steps {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 32px;
}
.steps li { background: var(--ice-soft); border: 1px solid var(--rule); border-radius: 10px; padding: 32px; }
.step-n { font-family: var(--display); font-size: 52px; color: var(--blue-bright); line-height: 1; }
.steps h3 { margin: 18px 0 10px; color: var(--ink); }
.steps p { margin: 0; font-size: 15.5px; line-height: 1.65; }
#process .center { margin-top: 48px; margin-bottom: 0; }

/* ---------- service area ---------- */

.area-list { font-size: 16.5px; line-height: 1.8; }

/* Service area: the whole of Virginia sits as a faint background layer, with the
   copy on top of it. The state is anchored to the right/center so the text column
   falls over the emptier western part of the map. */
.area-section { position: relative; overflow: hidden; }
.area-bg {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  display: flex; align-items: center; justify-content: flex-end;
}
.area-map {
  width: min(88%, 1000px); height: 100%; max-height: 480px;
  transform: translateY(40px);
}
/* .area-content keeps the standard centered 1180 wrap so its left edge lines up with
   every other section; the copy inside is capped and left-aligned rather than the
   whole block being centered (which read as floating in the middle). */
.area-content { position: relative; z-index: 1; }
.area-content > * { max-width: 560px; margin-right: auto; }

@media (max-width: 860px) {
  /* No room to sit text beside the map on a phone — let Virginia fill the width as
     a faint backdrop and drop its contrast so the copy over it stays readable. */
  .area-bg { justify-content: center; opacity: .5; }
  .area-map { width: 118%; transform: translateY(6%); max-height: none; }
  /* At phone width the map is too small to carry labels legibly — the outline
     and the town list below it do the work instead. */
  .map-anchor, .map-caption, .map-city { display: none; }
  .area-content { max-width: none; }
}

/* Real state boundary (simplified), equirectangular around Fredericksburg at
   2 SVG units per mile — so the dashed circle is a true 50-mile radius, not decoration. */
.map-state path { fill: rgba(44, 58, 140, .1); stroke: #8f95bb; stroke-width: 2; stroke-linejoin: round; }
/* Was a 50-mile radius circle; now the region bounded by Richmond, DC,
   Harrisonburg and Charlottesville. Same treatment — a dashed edge reads as
   "roughly this area" rather than a hard border we'd have to defend. */
.map-region { fill: rgba(44, 58, 140, .12); stroke: var(--blue-bright); stroke-width: 3; stroke-dasharray: 8 9; }
.map-corner { fill: var(--blue-bright); }
.map-city { font-family: var(--sans); font-size: 17px; font-weight: 600; fill: var(--ink-mid); }
.map-town { fill: #8f95bb; }
.map-home { fill: var(--blue); }
.map-base { fill: var(--blue); opacity: .7; }
.map-anchor { font-family: var(--display); fill: var(--ink); font-size: 26px; text-anchor: middle; }
.map-caption { font-family: var(--sans); fill: var(--ink-soft); font-size: 19px; letter-spacing: 3px; text-anchor: middle; }
.range-msg {
  margin: 18px 0 0; font-size: 16px; line-height: 1.6; color: var(--ink);
  background: var(--ice-soft); border: 1px solid var(--rule); border-left: 3px solid var(--blue);
  border-radius: 6px; padding: 14px 18px;
}
#range-btn { margin-top: 24px; }

/* ---------- faq ---------- */

/* Scoped away from .navdrop: these were written as bare `details` rules when the
   FAQ was the only disclosure on the site, and they otherwise put a rule line and
   16px of padding through the services menu in the header. */
details:not(.navdrop) { border-bottom: 1px solid var(--rule); padding: 6px 0; }
details:not(.navdrop) summary {
  cursor: pointer; list-style: none; display: flex; justify-content: space-between;
  align-items: center; gap: 16px; font-size: 18px; font-weight: 600; color: var(--ink);
  padding: 16px 0; min-height: 44px;
}
details summary::-webkit-details-marker { display: none; }
.faq-chev { color: var(--blue-bright); font-size: 22px; line-height: 1; transition: transform .2s ease; }
details[open] .faq-chev { transform: rotate(45deg); }
details p { margin: 0 0 20px; font-size: 16px; }

/* ---------- booking ---------- */

.book-head { max-width: 760px; margin-inline: auto; }
.book-head .lede { font-size: 18px; color: var(--mist); margin: 24px auto 0; max-width: 52ch; }
.book-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 24px; margin-top: 56px; align-items: start;
}
.book-grid-2 { max-width: 900px; margin-inline: auto; }
.book-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.book-card {
  background: var(--navy-deep); border: 1px solid rgba(238, 240, 251, .1);
  border-radius: 12px; padding: 32px;
}
.book-card h3 { font-family: var(--display); font-weight: 400; font-size: 24px; margin: 14px 0 10px; }
.book-copy { font-size: 15px; line-height: 1.65; color: var(--mist-dim); margin-bottom: 24px; }
.book-card .eyebrow { margin-bottom: 0; font-size: 12px; letter-spacing: .05em; }

#callback-form { display: flex; flex-direction: column; gap: 12px; margin-top: 8px; }
#callback-form input, #callback-form textarea {
  width: 100%; background: var(--navy); border: 1px solid rgba(238, 240, 251, .2);
  border-radius: 6px; padding: 13px 14px; color: var(--ice);
  font-size: 15px; font-family: inherit; min-height: 46px;
}
#callback-form textarea { resize: vertical; }
#callback-form ::placeholder { color: #6b74a8; opacity: 1; }
#callback-form input:focus, #callback-form textarea:focus { border-color: var(--sky); }
.form-status {
  margin: 16px 0 0; font-size: 16px; line-height: 1.7; color: var(--mist-bright);
  background: rgba(147, 167, 242, .1); border: 1px solid rgba(147, 167, 242, .35);
  border-radius: 8px; padding: 18px 20px;
}
.form-status a { color: var(--sky); }

/* Success and failure need to be distinguishable without reading, and without
   relying on colour alone -- the wording carries the meaning too. */
.form-status.is-ok {
  color: var(--ice);
  background: rgba(126, 217, 163, .12); border-color: rgba(126, 217, 163, .45);
}
.form-status.is-error {
  background: rgba(255, 155, 155, .1); border-color: rgba(255, 155, 155, .45);
}

/* Turnstile mounts here. It has no size until the script renders it, so the
   margin is on the widget rather than the container -- an empty container must
   not leave a gap for the visitors who never trigger the lazy load. */
.turnstile:not(:empty) { margin: 4px 0 2px; }
.turnstile iframe { max-width: 100%; }

/* The card the booking form is replaced by once a request goes through. It has
   to read as finished at a glance -- the previous version hid the form and left
   the card still headed "Request an inspection", which said the opposite of
   what had happened. */
.book-done { text-align: center; padding: 8px 0 4px; }
.book-done:focus { outline: none; }
.book-done:focus-visible { outline: 3px solid var(--sky); outline-offset: 6px; border-radius: 8px; }
.book-done-tick { color: #7ed9a3; margin: 0 auto 14px; }
.book-done h3 { font-family: var(--display); font-size: 30px; color: var(--ice); margin-bottom: 10px; }
.book-done .book-copy { margin-bottom: 14px; }
.book-done-call { margin: 0 0 18px; font-size: 15px; color: var(--mist-dim); }
.book-done-call a { color: var(--sky); font-weight: 600; }

/* Honeypot. Deliberately NOT display:none or hidden -- the better bots skip
   fields hidden that way, which is exactly the population this is meant to
   catch. Pushed off-canvas instead, with aria-hidden and tabindex="-1" on the
   markup so no real person, sighted or otherwise, ever reaches it. */
.hp {
  position: absolute; left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
}

/* ---------- footer ---------- */

.site-footer { background: var(--navy-deep); border-top: 1px solid rgba(238, 240, 251, .08); }
.footer-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 36px; padding-block: 56px 28px;
}
.footer-brand { gap: 12px; }
.footer-brand .brand-mark { width: 46px; height: 46px; }
.footer-brand .brand-name { font-size: 19px; }
.footer-tag { color: var(--mist-dim); font-size: 14px; margin: 14px 0 0; line-height: 1.6; }
.site-footer h3 {
  font-family: var(--script); font-weight: 400; font-size: 12px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--sky); margin-bottom: 12px;
}
.site-footer p { color: var(--mist-bright); font-size: 15px; line-height: 1.9; margin: 0; }
.footer-links { display: flex; flex-direction: column; }
.footer-links a {
  color: var(--mist-bright); text-decoration: none; font-size: 16px;
  display: inline-flex; align-items: center; min-height: 44px; width: fit-content;
}
.footer-links a:hover { color: var(--sky); }
.footer-legal { padding-bottom: 32px; }
.footer-legal p {
  color: var(--mist-faint); font-size: 13px; margin: 0;
  border-top: 1px solid rgba(238, 240, 251, .08); padding-top: 20px;
}

/* ---------- sticky mobile action bar ---------- */

.actionbar { display: none; }

/* ---------- responsive ---------- */

@media (max-width: 980px) {
  .split-wide-left, .split-wide-right { grid-template-columns: 1fr; gap: 44px; }
}
@media (max-width: 860px) {
  .hero-inner { padding-block: 56px; }
  .hero-figure { width: min(360px, 82%); margin: 0 0 28px; }
  .header-area { display: none; }
  .areastrip-inner { gap: 14px; }
  .areastrip-copy { flex-basis: 100%; }
  .area-check { flex-basis: 100%; }
  .cert { flex-direction: column; }
  .cert picture { width: min(260px, 70%); }
}
@media (max-width: 560px) {
  body { padding-bottom: 84px; }
  main section[id], .panel[id] { scroll-margin-top: 112px; }
  /* Phones: get both CTAs above the fold. The sticky header already carries the raccoon
     mark and the wordmark, so the hero crest is trimmed a little here — but it holds a
     baked-in wordmark, so it stays large enough to read rather than shrinking to a chip. */
  .hero-inner { padding-top: 30px; }
  .hero-figure { width: min(280px, 68%); margin-bottom: 14px; }
  .hero .eyebrow { margin-bottom: 12px; }
  .hero .lede { margin-top: 16px; }
  .hero-actions { margin-top: 20px; gap: 12px; }
  /* Two short labels rather than one long phone number: quicker to recognize, and
     each half is still a comfortable 48px target. */
  .actionbar {
    display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 100;
    background: rgba(7, 9, 26, .4);
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: 0 -4px 18px rgba(0, 0, 0, .3);
  }
  .actionbar-btn {
    display: flex; align-items: center; justify-content: center; gap: 9px;
    min-height: 56px; padding: 14px 10px;
    color: #fff; text-decoration: none; font-weight: 700; font-size: 16.5px;
  }
  .actionbar-call { background: var(--blue); }
  .actionbar-text { background: var(--navy); }
  .actionbar-btn:hover { color: #fff; }

  .header-right .btn-number { display: none; }
  .header-right .btn-label { display: inline; }
  /* Call and Text have to fit beside the badge on a 360px phone, and the badge is
     itself the wordmark — so the repeated text lockup is what gives way. */
  .brand-text { display: none; }
  .brand-mark { width: 46px; height: 46px; }
  .door-pair { grid-template-columns: 1fr; }
  .photo-offset { padding-top: 0; }
  .chip { font-size: 15px; padding: 10px 15px; }
  .inspection-cta .btn, .panel-cta .btn, .book-actions .btn, .owner-actions .btn { flex: 1 1 auto; }
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ==========================================================================
   DIVISION SUBPAGES
   Wild Bunch is planned to grow into several divisions (wildlife control today;
   home remodeling and cleaning later), so every page below the homepage lives
   under a division segment — /wildlife-removal/... . These components are the
   shared furniture for those pages. They reuse the same tokens, sections and
   buttons as the homepage on purpose: a service page should read as the same
   company, just narrower in scope.
   ========================================================================== */

/* ---------- breadcrumb ---------- */

/* Sits on the dark header ground, directly under the division nav. Doubles as
   the visible counterpart to the BreadcrumbList JSON-LD each subpage carries. */
.breadcrumb { background: var(--navy-deep); border-top: 1px solid rgba(238, 240, 251, .08); }
.breadcrumb ol {
  list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 0; padding: 12px 0; font-size: 13.5px;
}
.breadcrumb li { display: flex; align-items: center; gap: 8px; color: var(--mist-faint); }
.breadcrumb li + li::before { content: "›"; color: var(--mist-faint); }
.breadcrumb a { color: var(--mist-dim); text-decoration: none; }
.breadcrumb a:hover { color: var(--sky); text-decoration: underline; }
.breadcrumb [aria-current="page"] { color: var(--mist-bright); }

/* ---------- subpage hero ---------- */

/* Deliberately shorter than the homepage hero: someone landing here from a
   search for "squirrels in my attic" has already self-qualified, so the job is
   to confirm they're in the right place and get the phone number in reach. */
.subhero { background: var(--navy); padding-block: clamp(44px, 5.5vw, 72px); }
.subhero h1 { color: var(--ice); font-size: clamp(36px, 5vw, 60px); max-width: 18ch; }
.subhero .lede { color: var(--mist-bright); max-width: 60ch; margin-top: 20px; }
.subhero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

/* ---------- long-form content ---------- */

/* Service pages are the only place on this site with sustained prose, so they
   need heading rhythm the one-page layout never did. 68ch beats the 62ch used
   elsewhere because these paragraphs are read, not scanned. */
/* h2 is margin:0 globally, which works on the homepage because every h2 there is
   followed by a .section-sub that carries its own spacing. In prose an h2 is
   followed straight by body copy, so it needs the gap itself. */
.prose > h2 { margin: 8px 0 20px; }
.prose > .eyebrow + h2 { margin-top: 0; }
.prose > h3 {
  font-family: var(--display); font-weight: 400; font-size: clamp(23px, 2.4vw, 30px);
  line-height: 1.15; margin: 44px 0 14px;
}
.prose > h3:first-child { margin-top: 0; }
.prose p { max-width: 68ch; }
.prose > ul { margin: 0 0 22px; padding-left: 22px; }
.prose > ul li { margin-bottom: 10px; color: var(--ink-mid); max-width: 66ch; }
.section-forest .prose > ul li, .section-deep .prose > ul li { color: var(--mist); }

/* ---------- service directory ---------- */

/* The hub page's index of the division. Cards are whole-surface links: the
   entire card is the hit target, not just the heading. */
.svc-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
  gap: 20px; margin-top: 40px;
}
.svc-card {
  display: flex; flex-direction: column; gap: 8px;
  background: #fff; border: 1px solid var(--rule); border-left: 3px solid var(--blue);
  border-radius: 8px; padding: 24px 26px; text-decoration: none;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.svc-card:hover {
  transform: translateY(-2px); border-left-color: var(--blue-dark);
  box-shadow: 0 18px 34px -22px rgba(7, 9, 26, .45);
}
.svc-card h3 { color: var(--ink); margin: 0; }
.svc-card p { color: var(--ink-mid); font-size: 15.5px; line-height: 1.6; margin: 0; max-width: none; }
.svc-card .svc-go { color: var(--blue); font-weight: 600; font-size: 14.5px; margin-top: auto; padding-top: 8px; }
.svc-card:hover .svc-go { color: var(--blue-dark); }

/* ---------- signs / symptom list ---------- */

/* "Am I hearing what this page describes?" — the question a species page has to
   answer in the first screenful. Checkmark rules echo .includes on purpose. */
.signs { list-style: none; margin: 28px 0 0; padding: 0; }
.signs li {
  position: relative; padding: 13px 8px 13px 32px; border-bottom: 1px solid var(--rule);
  color: var(--ink-mid); font-size: 16.5px; line-height: 1.6; max-width: 68ch;
}
.signs li::before {
  content: ""; position: absolute; left: 6px; top: 22px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--blue);
}
.section-forest .signs li, .section-deep .signs li {
  color: var(--mist); border-bottom-color: rgba(238, 240, 251, .12);
}
.section-forest .signs li::before, .section-deep .signs li::before { background: var(--sky); }

/* ---------- product shots ---------- */

/* The client's own product photos, all portrait collages at the same 9:16, so a
   row of them lines up without cropping. Unlike .gallery these keep their native
   aspect ratio — each is a multi-panel composite, and a square crop would cut
   panels off the way it would a before/after. */
.product-shots {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 20px; margin-top: 44px; align-items: start;
}
.product-shots figcaption { margin-top: 8px; }

/* ---------- closing CTA band ---------- */

/* Subpages end here instead of repeating the homepage's two-card booking block:
   one clear action, and the form stays in one place at /#book. */
.cta-band { background: var(--navy); text-align: center; padding-block: clamp(56px, 7vw, 80px); }
.cta-band h2 { color: var(--ice); }
.cta-band p { color: var(--mist); margin-inline: auto; }
.cta-band-actions {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 28px;
}
/* Same button row used mid-page, where it sits under left-aligned prose. */
.cta-band-actions.actions-start { justify-content: flex-start; }

/* ---------- related pages ---------- */

.related { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
.related a {
  display: inline-flex; align-items: center; min-height: 44px; padding: 10px 18px;
  background: #fff; border: 1px solid var(--rule); border-radius: 999px;
  font-size: 15.5px; font-weight: 600; color: var(--ink); text-decoration: none;
}
.related a:hover { border-color: var(--blue); color: var(--blue); }
/* A pill row is a block of tap targets, not a paragraph — anything following it
   needs more air than the default 1em. */
.related + p { margin-top: 26px; }

@media (max-width: 560px) {
  .subhero-actions .btn, .cta-band-actions .btn { flex: 1 1 auto; }
  .prose > h3 { margin-top: 34px; }
}
