/* ============================================================
   CDT Contracting Group, Design System & Site Styles
   Static site · no build step · en-US
   ============================================================ */

/* ---------- Fonts (self-hosted) ---------- */
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../assets/fonts/barlowcond-600-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/barlowcond-700-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/barlow-400-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../assets/fonts/barlow-600-latin.woff2') format('woff2');
}
/* Metric-compatible fallback faces: during the swap window the local font is
   scaled to occupy the same advance width and line box as the web font, so the
   swap cannot move layout (intermittent CLS 0.002-0.006 in ~1/3 of cold loads,
   header nav/phone/CTA and arrival badges). Values computed from the actual
   font tables (hhea + weighted advance, _dev audit 2026-08-26); one face per
   loaded weight so bold fallbacks match bold web faces. On platforms without
   Arial Narrow/Arial the local() fails and the stack falls through unchanged. */
@font-face {
  font-family: 'Barlow Condensed Fallback';
  font-style: normal;
  font-weight: 600;
  src: local('Arial Narrow');
  size-adjust: 81.80%; ascent-override: 122.25%; descent-override: 24.45%; line-gap-override: 0%;
}
@font-face {
  font-family: 'Barlow Condensed Fallback';
  font-style: normal;
  font-weight: 700;
  src: local('Arial Narrow Bold');
  size-adjust: 81.85%; ascent-override: 122.17%; descent-override: 24.43%; line-gap-override: 0%;
}
@font-face {
  font-family: 'Barlow Fallback';
  font-style: normal;
  font-weight: 400;
  src: local('Arial');
  size-adjust: 95.42%; ascent-override: 104.80%; descent-override: 20.96%; line-gap-override: 0%;
}
@font-face {
  font-family: 'Barlow Fallback';
  font-style: normal;
  font-weight: 600;
  src: local('Arial Bold');
  size-adjust: 92.66%; ascent-override: 107.92%; descent-override: 21.58%; line-gap-override: 0%;
}

/* ---------- Design tokens ---------- */
:root {
  /* Color: black / orange / concrete grey, sampled from the client's mark */
  --black: #020202;        /* exact logo background; header uses this */
  --ink: #17191d;          /* charcoal for text and dark sections */
  --ink-2: #21242a;
  --orange: #f06000;       /* sampled from the logo T */
  --orange-deep: #b54700;  /* links and small accents on light bg (AA) */
  --orange-soft: #fdeadd;
  --bg: #f2f3f4;           /* concrete light */
  --white: #ffffff;
  --line: #e0e2e4;
  --text: #24272b;
  --muted: #575d64;
  --on-dark: #eceef0;
  --on-dark-muted: #aeb4bb;

  --grad-dark: linear-gradient(118deg, #020202 30%, #1d2027);

  /* Type */
  --font-head: 'Barlow Condensed', 'Barlow Condensed Fallback', 'Arial Narrow', Impact, sans-serif;
  --font-body: 'Barlow', 'Barlow Fallback', -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;

  /* Layout */
  --container: 1180px;
  --radius: 10px;
  --radius-lg: 16px;
  --shadow: 0 1px 2px rgba(2, 2, 2, .06), 0 8px 24px rgba(2, 2, 2, .07);
  --shadow-lift: 0 2px 4px rgba(2, 2, 2, .08), 0 16px 40px rgba(2, 2, 2, .14);
  --section-pad: clamp(56px, 9vw, 104px);
  --header-h: 64px;
  /* Height of the trust band, and therefore where the fold lands. Redefined
     per mode below; the arrival reads it at every width, so there is one
     number per mode and no literal repeated in a calc. This default is the
     stacked mobile band, which is what reduced-motion phones keep. */
  --trust-h: 120px;
}
/* Stacked band under reduced motion: 2 rows from 561 to 1020, 4 rows below
   561. Measured, not guessed: 4 rows render 142.6px, and leaving the old 120
   here pushed the fourth fact 22px past the fold on a phone. Order matters,
   the no-preference rule below must come last so the ticker still wins where
   motion is allowed. */
@media (max-width: 560px) { :root { --trust-h: 144px; } }
@media (min-width: 1021px) { :root { --trust-h: 96px; } }
@media (max-width: 1020px) and (prefers-reduced-motion: no-preference) {
  :root { --trust-h: 64px; }
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--text);
  background: var(--white);
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--orange-deep); }
a:hover { color: var(--orange); }
h1, h2, h3, h4 {
  font-family: var(--font-head);
  font-weight: 700;
  line-height: 1.12;
  color: var(--ink);
  margin: 0 0 .5em;
  text-wrap: balance;
  text-transform: uppercase;
  letter-spacing: .015em;
}
h1 { font-size: clamp(2.2rem, 5.4vw, 3.5rem); }
h2 { font-size: clamp(1.75rem, 3.6vw, 2.5rem); }
h3 { font-size: 1.3rem; }
p { margin: 0 0 1em; }
ul { padding-left: 1.2em; }

iframe:focus {
  /* iframes miss :focus-visible in Chromium; the map must show its ring */
  outline: 3px solid var(--orange);
  outline-offset: 2px;
}
:focus-visible {
  /* two-ring indicator: white inner ring + orange outer = visible on light AND dark */
  outline: 3px solid var(--orange);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--white);
  border-radius: 2px;
}
::placeholder { color: var(--muted); opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* The hidden attribute always wins. Author display rules on a class
   (e.g. .gallery-tile { display: block }) silently defeat the UA's
   [hidden] rule; this guard closes that entire defect class. */
[hidden] { display: none !important; }

/* atomic values (phone, email) never split mid-value */
.nowrap { white-space: nowrap; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.skip-link {
  position: absolute;
  left: 8px; top: -48px;
  z-index: 1300;
  background: var(--ink);
  color: var(--white);
  padding: 10px 16px;
  border-radius: 0 0 8px 8px;
  text-decoration: none;
  transition: top .15s ease;
}
.skip-link:focus { top: 0; color: var(--white); }

.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(16px, 4vw, 28px);
}
.section { padding-block: var(--section-pad); }
.section--tint { background: var(--bg); }
.section--dark { background: var(--ink); }
.section--dark h2, .section--dark h3 { color: var(--on-dark); }
.section--dark p { color: var(--on-dark-muted); }

.section-head { max-width: 720px; margin-bottom: clamp(28px, 5vw, 48px); }
.section-head--center { margin-inline: auto; text-align: center; }
.eyebrow {
  display: inline-block;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: .9rem;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--orange-deep);
  margin-bottom: 8px;
}
.section--dark .eyebrow { color: var(--orange); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  text-decoration: none;
  border-radius: var(--radius);
  padding: 13px 26px;
  border: 2px solid transparent;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease, transform .15s ease;
}
.btn--primary { background: var(--orange); color: var(--black); }
.btn--primary:hover { background: #ff791f; color: var(--black); transform: translateY(-1px); }
.btn--ghost { background: transparent; color: var(--on-dark); border-color: var(--on-dark-muted); }
.btn--ghost:hover { color: var(--white); border-color: var(--white); }
.btn--dark { background: var(--ink); color: var(--white); }
.btn--dark:hover { background: var(--ink-2); color: var(--white); }

/* ---------- Header ---------- */
.header {
  position: sticky;
  top: 0;
  z-index: 1100; /* above map iframes and all content */
  background: var(--black); /* exact logo background: mark sits seamless */
  border-bottom: 1px solid #26292e;
}
.header__bar {
  display: flex;
  align-items: center;
  gap: 18px;
  min-height: var(--header-h);
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  padding-block: 8px;
}
.brand img { height: 34px; width: auto; }
.brand__name {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--on-dark);
  white-space: nowrap;
}
.nav { margin-left: auto; }
.mobile-extra { display: none; } /* mobile-panel CTAs; shown only in the open panel */
.nav__list {
  display: flex;
  align-items: center;
  gap: 4px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav__item { position: relative; }
.nav__parent {
  display: inline-flex;
  align-items: stretch;
  border-radius: 8px;
}
/* label + caret read as ONE control: shared hover surface, no seam */
.nav__parent:hover, .nav__parent:focus-within { background: #1d2025; }
.nav__link {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--on-dark);
  text-decoration: none;
  padding: 9px 12px;
  border-radius: 8px;
}
.nav__parent .nav__link { border-radius: 8px 0 0 8px; padding-right: 6px; }
.nav__link:hover { color: var(--white); background: #1d2025; }
.nav__parent .nav__link:hover { background: transparent; }
.nav__caret {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  background: transparent;
  border: 0;
  border-radius: 0 8px 8px 0;
  color: var(--on-dark-muted);
  cursor: pointer;
  padding: 0;
}
.nav__caret svg { width: 12px; height: 12px; transition: transform .15s ease; }
.nav__caret:hover { color: var(--white); }
.nav__item.open .nav__caret svg { transform: rotate(180deg); }
.dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 230px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lift);
  padding: 8px;
  margin: 0;
  list-style: none;
  display: none;
  z-index: 1200;
}
.nav__item.open .dropdown { display: block; }
.dropdown a {
  display: block;
  padding: 9px 12px;
  border-radius: 8px;
  color: var(--text);
  text-decoration: none;
  font-size: .95rem;
}
.dropdown a:hover { background: var(--bg); color: var(--ink); }
.header__phone {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--on-dark);
  text-decoration: none;
  font-weight: 600;
  white-space: nowrap; /* atomic value: number never splits */
  padding: 8px 10px;
  border-radius: 8px;
}
.header__phone:hover { color: var(--white); background: #1d2025; }
.header__cta { white-space: nowrap; padding: 10px 18px; font-size: .95rem; }
.nav-toggle {
  display: none;
  margin-left: auto;
  background: transparent;
  border: 2px solid #33373d;
  border-radius: 8px;
  color: var(--on-dark);
  width: 44px;
  height: 40px;
  cursor: pointer;
  align-items: center;
  justify-content: center;
}
.nav-toggle svg { width: 20px; height: 20px; }

/* ---------- Hero ---------- */
.hero {
  background: linear-gradient(118deg, #020202 36%, #16181c 74%, #1d2027);
  color: var(--on-dark);
}
.hero__grid {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: clamp(28px, 5vw, 56px);
  align-items: center;
  padding-block: clamp(56px, 8vw, 96px);
}
.hero h1 { color: var(--white); margin-bottom: .4em; }
.hero__accent { color: var(--orange); }
.hero p { color: var(--on-dark-muted); font-size: 1.08rem; max-width: 560px; }
.hero__ctas { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 26px; }
.hero__media {
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid #2a2d33;
  box-shadow: var(--shadow-lift);
}
.hero__media img { width: 100%; height: 100%; object-fit: cover; }
.hero__badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: #101114;
  border: 1px solid #2a2d33;
  border-radius: 999px;
  padding: 7px 16px;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: .88rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--on-dark-muted);
  margin-bottom: 18px;
}
.hero__badge::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--orange);
}

/* ---------- Trust band ----------
   The band's height is not decorative: the arrival is sized
   calc(100svh - var(--header-h) - var(--trust-h)) so the band's bottom edge
   IS the fold. So the height is DECLARED here and the content is centred
   inside it, rather than the height falling out of padding plus a line box.
   The old 92px was hand-set against a band that actually rendered 93.97px,
   which put the fold 3px off at every desktop viewport; declaring it removes
   that class of drift. */
.trust { background: var(--orange); }
.trust__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
  min-height: var(--trust-h);
  align-items: stretch;
  padding-block: 14px;
}
.trust__item {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.15rem;
  line-height: 1.15;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--black);
}
/* the loop copies exist only for the ticker; everywhere else they are gone */
.trust__item--loop { display: none; }

/* THE TICKER, below 1021px only, and only when motion is allowed.
   Spacing is the items' OWN padding, never grid/flex `gap`: with 8 children
   a gap would make the track 8*item + 7*gap, so translating -50% would move
   4*item + 3.5*gap while one full set is 4*item + 4*gap. That half-gap
   mismatch is a visible jolt on every loop. Padding folds the spacing into
   the item, -50% is exactly one set, and the seam disappears. */
@media (max-width: 1020px) and (prefers-reduced-motion: no-preference) {
  .trust { overflow: hidden; }
  /* .trust .trust__grid, not .trust__grid: the stacked-layout rules further
     down the file re-apply `gap: 10px` at <=560, and with 8 children that is
     7 gaps of slack the -50% translate does not account for. It showed up as
     a 70px seam error in verify-mj.js. Raising specificity makes the ticker
     independent of source order rather than dependent on it. */
  .trust .trust__grid {
    display: flex;
    flex-wrap: nowrap;
    width: max-content;
    max-width: none;
    gap: 0;
    padding-inline: 0;
    padding-block: 0;
    height: var(--trust-h);
    min-height: 0;
    align-items: center;
    animation: trust-run 24s linear infinite;
  }
  .trust__item {
    flex: 0 0 auto;
    padding-inline: 32px;
    font-size: 1.45rem;
    white-space: nowrap;
  }
  .trust__item--loop { display: flex; }
  /* nothing moves while it is being read */
  .trust:hover .trust__grid,
  .trust:focus-within .trust__grid { animation-play-state: paused; }
}
@keyframes trust-run {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* Desktop: no motion, weight instead. The four facts fit on one line with
   room to spare, so a loop there would run with nothing to reveal. Hairline
   rules make the four read as one strip rather than four floating labels. */
@media (min-width: 1021px) {
  /* 1.45rem, not 1.6: at 1.6 the two long facts filled their 267.5px equal
     columns almost exactly and sat right up against the hairlines, which
     read as crowding rather than as weight. This keeps roughly 15px of air
     on each side of the longest item, asserted in verify-mj.js. */
  .trust__item { font-size: 1.45rem; padding-inline: 12px; }
  .trust__item + .trust__item:not(.trust__item--loop) {
    border-left: 1px solid rgba(2, 2, 2, .22);
  }
}

/* ---------- Feature cards (why choose us) ---------- */
.features {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 22px;
}
.feature {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 26px 22px 22px;
}
.feature__icon {
  width: 44px; height: 44px;
  border-radius: 10px;
  background: var(--orange-soft);
  color: var(--orange-deep);
  display: grid;
  place-items: center;
  margin-bottom: 14px;
}
.feature__icon svg { width: 22px; height: 22px; }
.feature h3 { margin-bottom: .35em; }
.feature p { margin: 0; color: var(--muted); font-size: .97rem; }

/* ---------- Services grid ---------- */
.services-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
}
.service-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden; /* image clipped by radius; nothing inside escapes */
  display: flex;
  flex-direction: column;
}
.service-card__media { aspect-ratio: 11 / 7; }
.service-card__media img { width: 100%; height: 100%; object-fit: cover; }
.service-card__body { padding: 20px 22px 22px; display: flex; flex-direction: column; flex: 1; }
.service-card h3 { margin-bottom: .3em; }
.service-card p { color: var(--muted); font-size: .96rem; margin-bottom: 14px; }
.service-card__link {
  margin-top: auto;
  font-family: var(--font-head);
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--orange-deep);
}
.service-card__link:hover { color: var(--orange); }

/* ---------- Gallery preview ---------- */
.gallery-note {
  display: inline-block;
  background: var(--orange-soft);
  color: var(--orange-deep);
  border-radius: 8px;
  padding: 6px 12px;
  font-size: .92rem;
  font-weight: 600;
  margin-bottom: 22px;
}
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}
.gallery-tile {
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  aspect-ratio: 4 / 3;
}
.gallery-tile img { width: 100%; height: 100%; object-fit: cover; }

/* GALLERY PAGE GRIDS: flex, not grid, so a short final row CENTRES.
   Scoped to the gallery page's own ids; the home preview keeps .gallery-grid
   as a plain grid because JS turns it into a carousel.
   Why flex: the filters change how many tiles are visible on every click,
   so no nth-child rule can catch the ragged tail. Filtering to Asphalt has
   always left a lone tile hanging at the left of its row; this fixes that.
   Two containers since the video row became its own zone (operator
   2026-08-25): same tile sizing in both, so clips and photographs read at
   one size even though they no longer share a container. */
#gallery-grid, #gallery-videos { display: flex; flex-wrap: wrap; justify-content: center; }
#gallery-grid > .gallery-tile, #gallery-videos > .gallery-tile { flex: 0 1 calc((100% - 36px) / 3); }
@media (max-width: 560px) {
  #gallery-grid > .gallery-tile, #gallery-videos > .gallery-tile { flex-basis: calc((100% - 18px) / 2); }
}

/* Zone labels: a short word and a hairline running to the container edge.
   This is the separation the operator asked to be LEGIBLE: the visitor sees
   in one glance where the clips end and the photographs begin, without a
   second card or a second background competing with the tiles. */
.gallery-zone {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 0 16px;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: .95rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}
.gallery-zone::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}
#zone-photos { margin-top: 40px; }

/* VIDEO TILE: same box, same size, same corner radius as a photo tile.
   The corner mark is a label and never a control, so it cannot go dead when
   script does not run; the native controls are the control, and they are
   present from first paint. */
.gallery-tile--video { position: relative; background: var(--ink); }
.gallery-tile__video {
  width: 100%; height: 100%;
  display: block;
  object-fit: cover;
}
.gallery-tile__clip {
  position: absolute;
  top: 10px; left: 10px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(2, 2, 2, .82);
  color: var(--white);
  font-family: var(--font-head);
  font-weight: 600;
  font-size: .85rem;
  letter-spacing: .06em;
  pointer-events: none;
}
.gallery-tile__clip svg { width: 9px; height: 11px; flex: none; }
/* once it is playing the label has nothing left to announce */
.gallery-tile--video[data-playing] .gallery-tile__clip { opacity: 0; }

/* Expand control on a looping tile (added by JS only in loop mode, so with
   script off it never exists and never sits dead). Bottom right, out of the
   way of the duration pill, always visible: it IS the obvious way to open
   the clip large now that the native controls are off in loop mode. */
.gallery-tile__expand {
  position: absolute;
  right: 10px; bottom: 10px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  border-radius: 50%;
  border: 0;
  background: rgba(2, 2, 2, .78);
  color: var(--white);
  cursor: pointer;
}
.gallery-tile__expand svg { width: 15px; height: 15px; }
.gallery-tile__expand:hover { background: var(--orange); color: var(--black); }
/* a looping tile is clickable everywhere, and the cursor should say so */
.gallery-tile--video:has(.gallery-tile__expand) { cursor: pointer; }

/* ---------- Process steps ---------- */
.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  counter-reset: step;
}
.step {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 26px 20px 22px;
}
.step__num {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--orange);
  color: var(--black);
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.2rem;
  display: grid;
  place-items: center;
  margin-bottom: 14px;
}
.step h3 { margin-bottom: .3em; }
.step p { margin: 0; color: var(--muted); font-size: .95rem; }

/* ---------- Quote form ---------- */
.quote { background: var(--ink); }
.quote .eyebrow { color: var(--orange); } /* on-dark: 5.35:1 on --ink (AA) */
.quote__grid {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: clamp(28px, 5vw, 56px);
  align-items: start;
}
.quote__intro h2 { color: var(--white); }
.quote__intro p { color: var(--on-dark-muted); }
.quote__contact { list-style: none; padding: 0; margin: 20px 0 0; }
.quote__contact li { margin-bottom: 12px; color: var(--on-dark); }
.quote__contact a { color: var(--on-dark); text-decoration: none; }
.quote__contact a:hover { color: var(--orange); }
.quote__contact .nowrap { white-space: nowrap; }
.form {
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift);
  padding: clamp(22px, 4vw, 32px);
}
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.form__field { margin-bottom: 14px; }
.form__field label {
  display: block;
  font-weight: 600;
  font-size: .92rem;
  margin-bottom: 5px;
  color: var(--ink);
}
.form__field input,
.form__field textarea {
  width: 100%;
  border: 1px solid #c9cdd1;
  border-radius: 8px;
  padding: 11px 12px;
  font: inherit;
  color: var(--text);
  background: var(--white);
}
.form__field input:focus-visible,
.form__field textarea:focus-visible { outline-offset: 0; box-shadow: none; }
.form__consent {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: .85rem;
  color: var(--muted);
  margin: 4px 0 16px;
}
.form__consent input { margin-top: 3px; width: 16px; height: 16px; flex: none; }
.form__status { margin-top: 12px; font-weight: 600; }
.form__status--ok { color: #1c7a2e; }
.form__status--err { color: #b3261e; }
.form .btn { width: 100%; }

/* ---------- FAQ ---------- */
.faq-list { max-width: 820px; margin-inline: auto; }
/* on /faq the accordion is the page's main column, not a centered island */
.faq-list--page { max-width: none; margin-inline: 0; }
.faq {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: 12px;
}
.faq__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.12rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--ink);
  padding: 18px 20px;
}
.faq__q svg { width: 14px; height: 14px; flex: none; transition: transform .15s ease; color: var(--orange-deep); }
.faq.open .faq__q svg { transform: rotate(180deg); }
.faq__a { display: none; padding: 0 20px 18px; color: var(--muted); }
.faq.open .faq__a { display: block; }

/* ---------- Service areas band ---------- */
.areas { background: var(--bg); }
.areas__grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: clamp(28px, 5vw, 56px);
  align-items: center;
}
.areas__card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 26px 24px;
}
.areas__card h3 { margin-bottom: .4em; }
.areas__card p { margin: 0; color: var(--muted); }

/* ---------- CTA band ---------- */
.cta-band { background: linear-gradient(118deg, #020202 30%, #1d2027); }
.cta-band__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding-block: clamp(40px, 6vw, 64px);
}
.cta-band h2 { color: var(--white); margin: 0; }
.cta-band__btns { display: flex; flex-wrap: wrap; gap: 14px; }

/* ---------- Map ---------- */
.map-embed { line-height: 0; }
.map-embed iframe {
  width: 100%;
  height: 430px;
  border: 0;
  display: block;
  filter: saturate(.85);
}

/* ---------- Footer ---------- */
.footer { background: var(--black); color: var(--on-dark-muted); }
.footer a { color: var(--on-dark-muted); text-decoration: none; }
.footer a:hover { color: var(--orange); }
.footer__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1.2fr;
  gap: clamp(28px, 5vw, 56px);
  padding-block: clamp(48px, 7vw, 72px);
}
.footer__brand img { width: 170px; margin-bottom: 16px; }
.footer__brand p { font-size: .95rem; margin: 0; }
.footer .footer__h {
  color: var(--on-dark);
  font-size: 1.02rem;
  letter-spacing: .08em;
  margin-bottom: 14px;
}
.footer ul { list-style: none; margin: 0; padding: 0; }
.footer li { margin-bottom: 9px; font-size: .95rem; }
.footer .nowrap { white-space: nowrap; }
.footer__bottom {
  border-top: 1px solid #22252a;
  padding-block: 18px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: space-between;
  font-size: .88rem;
}

/* ---------- Interior pages ---------- */
.page-hero {
  background: linear-gradient(118deg, #020202 36%, #16181c 74%, #1d2027);
  color: var(--on-dark);
  padding-block: clamp(44px, 6vw, 72px);
}
.page-hero h1 { color: var(--white); margin-bottom: .25em; }
.page-hero p { color: var(--on-dark-muted); max-width: 640px; margin: 0; font-size: 1.06rem; }
.prose { max-width: 820px; }
.prose h2 { font-size: clamp(1.4rem, 2.6vw, 1.8rem); margin-top: 1.6em; }
.prose h2:first-child { margin-top: 0; }
.prose ul { color: var(--text); }
.prose li { margin-bottom: 6px; }
.draft-notice {
  background: var(--orange-soft);
  border: 1px solid #f0c9a8;
  border-radius: var(--radius);
  color: var(--orange-deep);
  font-weight: 600;
  padding: 14px 18px;
  margin-bottom: 28px;
}
.about-grid {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: clamp(28px, 5vw, 56px);
  align-items: start;
}
.about-aside {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 26px 24px;
}
.about-aside h3 { margin-bottom: .5em; }
.about-aside ul { list-style: none; padding: 0; margin: 0; }
.about-aside li {
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
  color: var(--text);
  font-weight: 600;
}
.about-aside li:last-child { border-bottom: 0; }
.about-aside li span { display: block; font-weight: 400; color: var(--muted); font-size: .92rem; }
.contact-info {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 26px 24px;
}
.contact-info h3 { margin-bottom: .6em; }
.contact-info ul { list-style: none; padding: 0; margin: 0; }
.contact-info li { margin-bottom: 12px; color: var(--text); }
.contact-info a { color: var(--orange-deep); text-decoration: none; }
.contact-info a:hover { color: var(--orange); }
.status-page {
  min-height: 46vh;
  display: grid;
  place-items: center;
  text-align: center;
  padding-block: var(--section-pad);
}
.status-page .status-code {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: clamp(3.4rem, 9vw, 5.5rem);
  color: var(--orange);
  line-height: 1;
}
.status-page p { max-width: 520px; margin-inline: auto; color: var(--muted); }
.status-page .hero__ctas { justify-content: center; }
@media (max-width: 1020px) {
  .about-grid { grid-template-columns: 1fr; }
}

/* ---------- Shared hover matrix (single definition for all card groups) ---------- */
.feature, .service-card, .step, .gallery-tile, .areas__card {
  transition: transform .18s ease, box-shadow .18s ease;
}
.feature:hover, .service-card:hover, .step:hover, .gallery-tile:hover, .areas__card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
}
@media (prefers-reduced-motion: reduce) {
  .feature:hover, .service-card:hover, .step:hover, .gallery-tile:hover, .areas__card:hover {
    transform: none;
  }
}

/* ---------- Breakpoints ---------- */
@media (max-width: 1020px) {
  .nav, .header__phone, .header__cta { display: none; }
  .nav-toggle { display: inline-flex; }
  .header.nav-open .nav {
    display: block;
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    background: var(--black);
    border-bottom: 1px solid #26292e;
    max-height: calc(100vh - var(--header-h)); /* panel never extends past viewport */
    overflow-y: auto;
    padding: 10px clamp(16px, 4vw, 28px) 20px;
  }
  .header.nav-open .nav__list { flex-direction: column; align-items: stretch; gap: 2px; }
  .nav__parent { display: flex; justify-content: space-between; }
  .nav__parent .nav__link { flex: 1; }
  .nav__caret { width: 44px; min-height: 44px; }
  .dropdown {
    position: static;
    box-shadow: none;
    border: 0;
    background: #101114;
    display: none;
    padding: 2px 8px 8px;
  }
  .dropdown a { color: var(--on-dark-muted); }
  .dropdown a:hover { background: #1d2025; color: var(--white); }
  .header.nav-open .mobile-extra {
    display: flex;
    gap: 12px;
    margin-top: 14px;
    flex-wrap: wrap;
  }
  .mobile-extra { display: none; }
  .hero__grid { grid-template-columns: 1fr; }
  .features { grid-template-columns: repeat(2, 1fr); }
  .services-grid { grid-template-columns: repeat(2, 1fr); }
  .steps { grid-template-columns: repeat(2, 1fr); }
  .trust__grid { grid-template-columns: repeat(2, 1fr); }
  .quote__grid { grid-template-columns: 1fr; }
  .areas__grid { grid-template-columns: 1fr; }
  .footer__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .features { grid-template-columns: 1fr; }
  .services-grid { grid-template-columns: 1fr; }
  .steps { grid-template-columns: 1fr; }
  .trust__grid { grid-template-columns: 1fr; gap: 10px; }
  .footer__grid { grid-template-columns: 1fr; }
  .gallery-grid { grid-template-columns: repeat(2, 1fr); }
  .form__row { grid-template-columns: 1fr; }
}
/* odd last card spans full width on 2-col mobile grid: no orphan half-card */
@media (max-width: 1020px) and (min-width: 561px) {
  .services-grid .service-card:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

/* ---------- Service pages (Step 4) ---------- */
.breadcrumb {
  background: #020202;
  border-bottom: 1px solid #1b1e23;
  font-size: .88rem;
}
.breadcrumb ol {
  list-style: none;
  margin: 0;
  padding: 12px 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.breadcrumb li { color: var(--white); }
.breadcrumb li + li::before { content: "/"; color: var(--on-dark-muted); margin-right: 6px; }
.breadcrumb a { color: var(--on-dark-muted); text-decoration: none; }
.breadcrumb a:hover { color: var(--white); }
.svc-grid {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: clamp(28px, 5vw, 56px);
  align-items: start;
}
.svc-included {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 26px 24px;
}
.svc-included h3 { margin-bottom: .6em; }
.checklist { list-style: none; margin: 0; padding: 0; }
.checklist li {
  position: relative;
  padding: 9px 0 9px 28px;
  border-bottom: 1px solid var(--line);
  color: var(--text);
}
.checklist li:last-child { border-bottom: 0; }
.checklist li::before {
  content: "\2713";
  position: absolute;
  left: 2px;
  color: var(--orange-deep);
  font-weight: 700;
}
.features--three { grid-template-columns: repeat(3, 1fr); }
.photo-strip {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(14px, 2.5vw, 24px);
  margin-top: clamp(28px, 5vw, 44px);
}
.photo-strip .photo-slot { margin: 0; }
.photo-strip img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  border: 1px solid var(--line);
}
.photo-strip__note {
  color: var(--muted);
  font-size: .92rem;
  margin: 14px 0 0;
}
.related-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 2.5vw, 26px);
}
@media (max-width: 1020px) {
  .svc-grid { grid-template-columns: 1fr; }
  .related-grid { grid-template-columns: repeat(2, 1fr); }
  .features--three { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 1020px) and (min-width: 561px) {
  /* 3 cards on a 2-col grid: last card spans, no orphan half-card */
  .related-grid .service-card:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .features--three .feature:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
  .related-grid { grid-template-columns: 1fr; }
  .photo-strip { grid-template-columns: 1fr; }
  .features--three { grid-template-columns: 1fr; }
}

/* ---------- City pages (Step 5) ---------- */
.city-list { list-style: none; margin: 0 0 14px; padding: 0; }
.city-list li { padding: 8px 0; border-bottom: 1px solid var(--line); }
.city-list li:last-child { border-bottom: 0; }
.city-list a {
  color: var(--orange-deep);
  font-weight: 600;
  text-decoration: none;
}
.city-list a:hover { color: var(--orange); }
.city-chips { display: flex; flex-wrap: wrap; gap: 12px; }
.city-chip {
  display: inline-flex;
  align-items: center;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow);
  color: var(--ink);
  font-family: var(--font-head);
  font-weight: 600;
  letter-spacing: .02em;
  padding: 10px 20px;
  text-decoration: none;
  transition: transform .18s ease, box-shadow .18s ease, color .18s ease;
}
.city-chip:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lift);
  color: var(--orange-deep);
}
@media (prefers-reduced-motion: reduce) {
  .city-chip:hover { transform: none; }
}

/* ---------- Gallery page (Step 6) ---------- */
.filter-bar { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 20px; }
.filter-btn {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow);
  padding: 9px 20px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.filter-btn:hover { color: var(--orange-deep); }
.filter-btn[aria-pressed="true"] {
  background: var(--orange);
  border-color: var(--orange);
  color: var(--black);
}
.gallery-tile { display: block; }
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 1400; /* above sticky header (1100) and skip-link (1300) */
  background: rgba(2, 2, 2, .92);
  display: flex;
  align-items: center;
  justify-content: center;
}
.lightbox[hidden] { display: none; }
.lightbox img,
.lightbox video {
  max-width: min(1100px, 88vw);
  max-height: 84vh;
  width: auto;
  height: auto;
  border-radius: var(--radius);
}
.lightbox button {
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1px solid #3a3e44;
  background: #17191d;
  color: var(--on-dark);
  cursor: pointer;
}
.lightbox button:hover { color: var(--white); border-color: var(--white); }
.lightbox button svg { width: 18px; height: 18px; }
.lightbox__close { top: 18px; right: 18px; }
.lightbox__prev { left: 14px; top: 50%; transform: translateY(-50%); }
.lightbox__next { right: 14px; top: 50%; transform: translateY(-50%); }
@media (max-width: 560px) {
  .lightbox__prev { left: 6px; }
  .lightbox__next { right: 6px; }
}

/* ---------- Before/after pair (P2, placement pass) ---------- */
.ba-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(14px, 2.5vw, 24px);
}
.ba-pair__item { position: relative; margin: 0; }
.ba-pair__item img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
}
.ba-pair__badge {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 1;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: .92rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  padding: 5px 14px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--white);
}
.ba-pair__badge--after { background: var(--orange); color: var(--black); }
@media (max-width: 700px) {
  .ba-pair { grid-template-columns: 1fr; }
}

/* ---------- Video block (zero bytes until click: preload=none + poster) ---------- */
.video-block {
  position: relative;
  max-width: 900px;
}
.video-block video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  background: var(--black);
}
/* play affordance over the poster; never intercepts input */
.video-block::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background:
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 6.5l9 5.5-9 5.5z" fill="%23020202"/></svg>')
    center / 30px no-repeat,
    rgba(240, 96, 0, .95);
  box-shadow: 0 4px 18px rgba(2, 2, 2, .35);
  pointer-events: none;
}
.video-block.is-playing::after { display: none; }

/* ---------- Home gallery carousel (recomposed, polish pass) ---------- */
.carousel {
  max-width: 880px;
  margin-inline: auto; /* deliberate centred object */
}
.carousel__viewport {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lift);
}
.carousel__track {
  display: flex;
  transition: transform .45s ease;
}
.carousel__slide {
  flex: 0 0 100%;
  aspect-ratio: 4 / 3;
}
.carousel__slide img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* arrows live ON the image: the slide, controls and progress read as one object */
.carousel__btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 0;
  background: rgba(2, 2, 2, .62);
  color: var(--white);
  cursor: pointer;
}
.carousel__btn:hover { background: rgba(2, 2, 2, .85); color: var(--orange); }
.carousel__btn svg { width: 18px; height: 18px; }
.carousel__prev { left: 14px; }
.carousel__next { right: 14px; }
.carousel__bar {
  height: 3px;
  margin-top: 14px;
  background: var(--line);
  border-radius: 2px;
  overflow: hidden;
}
.carousel__bar-fill {
  height: 100%;
  width: 100%;
  background: var(--orange);
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform .45s ease;
}
.carousel__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 10px;
}
.carousel__counter {
  font-family: var(--font-head);
  font-weight: 600;
  letter-spacing: .06em;
  color: var(--muted);
}
/* labeled autoplay pill: text state, never mistakable for video playback */
.carousel__auto {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: .92rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--muted);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 8px 16px;
  cursor: pointer;
}
.carousel__auto-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--muted);
}
.carousel__auto.is-on { color: var(--ink); border-color: var(--orange); }
.carousel__auto.is-on .carousel__auto-dot { background: var(--orange); }
.carousel__auto:hover { color: var(--orange-deep); }
#gallery .hero__ctas { justify-content: center; } /* full-gallery button joins the centred object */

/* ---------- Why: editorial treatment (services + cities) ---------- */
.why-editorial {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: clamp(28px, 5vw, 64px);
  align-items: start;
}
.why-editorial__pull {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: clamp(1.25rem, 2.4vw, 1.7rem);
  line-height: 1.35;
  color: var(--ink);
  border-left: 4px solid var(--orange);
  padding-left: 18px;
  margin: 18px 0 0;
}
.why-editorial__body p { color: var(--text); }
.why-editorial__body p:first-child { margin-top: .2em; }
.why-editorial__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 22px;
}
@media (max-width: 860px) {
  .why-editorial { grid-template-columns: 1fr; }
}

/* ---------- About: aside follows the reader (dead-column fix) ---------- */
.about-aside--sticky {
  position: sticky;
  top: calc(var(--header-h) + 24px);
}
.about-aside__cta {
  width: 100%;
  margin-top: 18px;
}

/* ---------- FAQ page only: the aside is a panel spanning the question list.
   Scoped to .faq-grid so /about's identical markup is untouched.

   Its top edge sits on the h2's CAP-HEIGHT line, not the h2's box top: the
   measured gap between box top and first glyph pixel is 0.225 of the font
   size (9px at 40px, 6px at 28px), so the offset is expressed against the
   same clamp() the heading uses and tracks it at every width.
   Its bottom edge lands on the last FAQ card.

   Both edges come from grid geometry, not magic numbers: the aside spans the
   heading row through the list row, so when an accordion opens and the left
   column grows, the panel grows with it. ---------- */
@media (min-width: 1021px) {
  .faq-grid {
    grid-template-rows: auto auto auto;   /* kicker | heading | question list */
    /* the shared gap token is a COLUMN gap here: the three left-column rows
       keep their own margins, so a row gap would silently space them apart */
    row-gap: 0;
  }
  /* the left column's wrapper stops being a box so its three parts become
     grid items and can be addressed by row */
  .faq-grid > div { display: contents; }
  /* the kicker was an inline-block sitting in the wrapper's 1.65rem line box;
     as a grid item it loses the strut's descender space beneath it, which
     would lift the whole left column by 2px. Added back explicitly so nothing
     on the page moves. Both terms are root-relative, so this cannot drift
     with viewport width. */
  .faq-grid > div > .eyebrow {
    grid-column: 1; grid-row: 1;
    margin-bottom: calc(8px + 0.125rem);
  }
  .faq-grid > div > h2 { grid-column: 1; grid-row: 2; }
  .faq-grid > div > .faq-list { grid-column: 1; grid-row: 3; }
  /* the list is now a grid item, so the last card's bottom margin no longer
     collapses out of it; without this the row would end 12px below the card */
  .faq-grid .faq-list .faq:last-child { margin-bottom: 0; }

  .faq-grid > .about-aside {
    grid-column: 2;
    grid-row: 2 / 4;
    align-self: stretch;
    margin-top: calc(clamp(1.75rem, 3.6vw, 2.5rem) * 0.225);
    min-height: 0;
    /* composed at full height: intro group at the top, action at the bottom,
       the breathing room deliberately in the middle rather than pooled under
       the last element */
    display: flex;
    flex-direction: column;
    padding: 22px 24px;
  }
  /* the contact rows absorb the extra height, so a taller panel reads as an
     evenly spaced directory rather than a block of content with a hole
     punched above the button */
  .faq-grid > .about-aside ul {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  .faq-grid > .about-aside li {
    padding: 8px 0;
    flex: 1 1 auto;
    display: flex;
    align-items: center;
  }
  .faq-grid > .about-aside .about-aside__cta { margin-top: 16px; }
}
/* Narrow end of the two-column range: the aside column is at its tightest
   here, so its paragraph wraps to three lines and the card would be taller
   than the question list it must match. A slightly tighter rhythm keeps it
   inside the span instead of forcing the grid rows apart. */
@media (min-width: 1021px) and (max-width: 1200px) {
  .faq-grid > .about-aside { padding: 16px 20px; }
  .faq-grid > .about-aside li { padding: 4px 0; }
}

/* ---------- Header brand: full name at every width (Rob's direction).
   Stacked like the real lockup (CDT above, CONTRACTING GROUP beneath),
   which makes the whole unit NARROWER than the old mark-alone state, so
   the nav never competes with it at any width. ---------- */
.brand {
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
}
.brand img { height: 26px; }
.brand__name {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: .62rem;
  letter-spacing: .26em;
  color: var(--on-dark-muted);
  border-left: 0;
  padding-left: 2px;
  line-height: 1;
}
.nav { margin-left: auto; padding-left: 18px; }

/* ---------- Even card grids (no orphan cell rows) ---------- */
@media (min-width: 1021px) {
  .services-grid { grid-template-columns: repeat(4, 1fr); } /* 8 cards = 4+4 */
  .services-grid--five { grid-template-columns: repeat(6, 1fr); } /* 5 cards = 3+2 centred */
  .services-grid--five .service-card { grid-column: span 2; }
  .services-grid--five .service-card:nth-child(4) { grid-column: 2 / span 2; }
  .services-grid--five .service-card:nth-child(5) { grid-column: 4 / span 2; }
}

/* ---------- Motion system ----------
   Doctrine: motion confirms structure. One-time entrance reveals establish
   reading order, hover states acknowledge intent; nothing moves while being
   read, nothing loops. Transform/opacity only. JS applies .reveal ONLY when
   prefers-reduced-motion is not set, so no-JS and reduced-motion users get
   the complete static page. */
.reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .55s ease, transform .55s ease;
  transition-delay: calc(var(--reveal-i, 0) * 90ms);
}
.reveal.is-in {
  opacity: 1;
  transform: none;
}
.service-card__media { overflow: hidden; }
.service-card__media img { transition: transform .35s ease; }
.service-card:hover .service-card__media img { transform: scale(1.04); }
@media (prefers-reduced-motion: reduce) {
  .service-card:hover .service-card__media img { transform: none; }
}

/* ---------- DeSoto County map, second design (operator rejected v1:
   washed out, oversized, floating labels, lost marker). The map is now a
   dark-field brand panel: the county sits as a lifted dark shape on the
   panel's own field, the five cities are the saturated brand orange, and
   the piece is contained instead of dominating the page. Real Census
   geometry throughout; see the generator. ---------- */
.cmap {
  max-width: 680px;
  margin-inline: auto;
  background: var(--grad-dark);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift);
  padding: clamp(14px, 3vw, 26px);
}
.cmap__svg { display: block; width: 100%; height: auto; }
.cmap__county {
  fill: #2b3038;                      /* lifted a step off the panel field */
  stroke: rgba(255, 255, 255, .16);
  stroke-width: 1.2;
  stroke-linejoin: round;
}
.cmap__city {
  fill: var(--orange);
  stroke: #020202;
  stroke-width: 1;
  stroke-linejoin: round;
}
/* city pages: everything that is not the subject steps back to an outline */
.cmap__city--ghost {
  fill: rgba(240, 96, 0, .13);
  stroke: rgba(240, 96, 0, .55);
  stroke-width: 1.2;
}
.cmap__city--hl { fill: var(--orange); stroke: #020202; }
.cmap a .cmap__city { transition: fill .15s ease; }
.cmap a:hover .cmap__city, .cmap a:focus-visible .cmap__city { fill: #ff791f; }
.cmap a:hover .cmap__label--dark { fill: var(--black); }
.cmap a:focus-visible { outline: 3px solid var(--white); outline-offset: 2px; }
.cmap__label {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 16px;
  letter-spacing: .06em;
  text-transform: uppercase;
  pointer-events: none;
}
/* ground-matched halos: an in-shape label crosses the black boundary
   strokes and the shape's own notches (Hernando measured 1.18:1 where its
   glyphs hit a boundary line), and a field label can graze an orange edge
   (Horn Lake measured 2.83:1). The halo is the label's own ground colour,
   so it is invisible in place and guarantees what sits behind every glyph. */
.cmap__label--dark {
  fill: var(--black);
  stroke: var(--orange);
  stroke-width: 3.5px;
  paint-order: stroke;
  stroke-linejoin: round;
}
.cmap__label--light {
  fill: var(--on-dark);
  stroke: #2b3038;
  stroke-width: 3.5px;
  paint-order: stroke;
  stroke-linejoin: round;
}
.cmap__leader {
  stroke: var(--on-dark-muted);
  stroke-width: 1.4;
  stroke-dasharray: 1 3;
  stroke-linecap: round;
}
.cmap__state {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: .3em;
  fill: var(--on-dark-muted);
}
.cmap__wordmark {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 30px;
  letter-spacing: .2em;
  fill: rgba(174, 180, 187, .5);      /* on-dark-muted, pulled back: ground, not subject */
}
.cmap__wordmark--sub { font-size: 14px; letter-spacing: .5em; fill: rgba(174, 180, 187, .38); }
/* Small screens: the SVG scales the whole scene down to about half, which
   took the 16px labels to an unreadable 8. The type steps UP as the map
   steps down, so the rendered size stays legible; positions were re-checked
   at 390 after the bump. */
@media (max-width: 560px) {
  .cmap__label { font-size: 24px; }
  .cmap__hq-label { font-size: 19px; }
  .cmap__state { font-size: 17px; }
  .cmap__wordmark { font-size: 38px; }
  .cmap__wordmark--sub { font-size: 19px; }
}
/* the base marker anchors the read: ringed target plus its own named label */
.cmap__hq-ring {
  fill: none;
  stroke: var(--white);
  stroke-width: 2.6;
}
.cmap__hq-core { fill: var(--white); }
.cmap__hq-label {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .14em;
  fill: var(--black);
  /* halo so the marker label survives whatever ground it crosses */
  stroke: rgba(255, 255, 255, .85);
  stroke-width: 3px;
  paint-order: stroke;
  stroke-linejoin: round;
}

/* ---------- Home entrance choreography (MJ feedback, 2026-08-25) ----------
   One coreography, one timeline, fired once at load and never again:
     0.00s  location badge settles from above
     0.12s  headline reveals word by word, 0.08s apart
     0.55s  subtitle rises
     0.65s  the two CTAs follow, 0.08s apart
     0.55s  trust band facts arrive staggered (desktop) or the band fades
            in as one unit where it runs as a ticker
   All of it is transform and opacity with `both` fill, so nothing is ever
   hidden by layout and CLS stays exactly 0. Every rule is scoped under
   html.cdt-entry, which ONLY the inline head script on the home page adds,
   and only when reduced motion is off: no JS or reduced motion means none
   of this exists and the page is complete at first paint. The comparator
   itself (photographs, BEFORE/AFTER badges, grip) is deliberately NOT in
   the timeline: it is the subject of the first screen and the LCP element,
   and the choreography serves it rather than competing with it. */
@keyframes cdt-entry-rise {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: none; }
}
@keyframes cdt-entry-settle {
  from { opacity: 0; transform: translateY(-12px); }
  to { opacity: 1; transform: none; }
}
html.cdt-entry .arr__copy .hero__badge {
  animation: cdt-entry-settle .6s cubic-bezier(.2, .9, .3, 1.18) both;
}
html.cdt-entry .arr__copy h1 .ew {
  display: inline-block; /* transformable; changes nothing visually */
  animation: cdt-entry-rise .7s cubic-bezier(.22, .8, .3, 1) both;
  animation-delay: calc(.12s + var(--ei, 0) * .08s);
}
html.cdt-entry .arr__copy .arr__sub {
  animation: cdt-entry-rise .7s ease-out .55s both;
}
html.cdt-entry .arr__copy .hero__ctas .btn {
  animation: cdt-entry-rise .7s ease-out .65s both;
}
html.cdt-entry .arr__copy .hero__ctas .btn + .btn { animation-delay: .73s; }
/* trust band: the surface paints immediately (first-viewport discipline says
   the fold edge is never an empty strip waiting on a reveal); only the FACTS
   inside it arrive staggered, and they are done inside 1.5s of load */
@media (min-width: 1021px) {
  html.cdt-entry .trust__item { animation: cdt-entry-rise .8s ease-out both; }
  html.cdt-entry .trust__item:nth-child(1) { animation-delay: .55s; }
  html.cdt-entry .trust__item:nth-child(2) { animation-delay: .63s; }
  html.cdt-entry .trust__item:nth-child(3) { animation-delay: .71s; }
  html.cdt-entry .trust__item:nth-child(4) { animation-delay: .79s; }
}
/* Below 1021 the band gets NO entrance at all, deliberately. The first
   version rose the whole band 12px and the fold assertion caught the band's
   bottom edge 11.78px off at 390: the band IS the fold line, and the
   first-viewport rule says the fold edge is complete at first paint. The
   ticker starting to run is already the band's arrival. */

/* single-image strip: a deliberate one-photo composition, not a half-empty pair */
.photo-strip--single {
  grid-template-columns: 1fr;
  max-width: 760px;
  margin-inline: auto;
}


/* ---------- Area cards: text-led (operator call: an area is a place,
   not a project; no job photo, no location implication) ---------- */
.service-card--area {
  border-top: 4px solid var(--orange);
  padding: 4px 0 0;
}
.service-card--area .service-card__body { padding-top: 20px; }
.service-card--area .service-card__kicker {
  display: block;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: .82rem;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--muted);
  margin-bottom: 6px;
}

/* ---------- First viewport: black + orange only (operator, 2026-08-19).
   Hero grows so hero + trust band exactly fill the first screen at any
   desktop viewport height; the white content field begins at the fold,
   never inside it. Mobile already overfills the fold and stays as is. */
@media (min-width: 1021px) {
  /* First-viewport composition (operator direction 2026-08-19): the
     photograph carries the weight, the band is thicker, and the vertical
     rhythm is tightened so the screen reads full, not padded. The band
     edge still lands exactly at the fold via the same calc.
     --trust-h moved to :root (2026-08-25) so the arrival can read it at
     every width, not only here, and so its value is declared once per
     mode. It also went 92 -> 96 because the band's own height is now
     declared rather than inferred from padding. */
  .hero {
    display: flex;
    align-items: center;
    min-height: calc(100svh - var(--header-h) - var(--trust-h));
  }
  .hero .container { width: 100%; }
  .hero__grid {
    grid-template-columns: 1fr 1.4fr; /* the photograph is the larger column */
    gap: clamp(32px, 4vw, 48px);
    padding-block: clamp(24px, 3vw, 40px);
  }
  /* THE LAYOUT SERVES THE IMAGE: the media box matches the retouched
     photo's own 16:9, so nothing is cropped away. Right edge aligned to
     the CONTENT CONTAINER (operator, 2026-08-19): the hero grid lives
     inside .container (max-width var(--container) + padding-inline), so
     width:100% of the grid column ends exactly on the same right gutter
     the header CTA sits on. No bleed, no hand-tuned pixels. */
  .hero__media {
    height: auto;
    aspect-ratio: 16 / 9;
    width: 100%;
  }
  .hero__badge { margin-bottom: 16px; }
  .hero__ctas { margin-top: 22px; }
}

/* ---------- Before/after drag-reveal slider (progressive enhancement:
   no-JS keeps the static labeled pair; JS builds this) ---------- */
.ba-slider {
  position: relative;
  max-width: 880px;
  margin-inline: auto;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lift);
}
.ba-slider img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.ba-slider__after { will-change: clip-path; }
.ba-slider__badge {
  position: absolute;
  top: 12px;
  z-index: 3;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: .92rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  padding: 5px 14px;
  border-radius: 999px;
}
.ba-slider__badge--before { left: 12px; background: var(--ink); color: var(--white); }
.ba-slider__badge--after { right: 12px; background: var(--orange); color: var(--black); }
.ba-slider__line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 3px;
  margin-left: -1.5px;
  background: var(--white);
  box-shadow: 0 0 6px rgba(2, 2, 2, .5);
  z-index: 2;
  pointer-events: none;
}
.ba-slider__handle {
  position: absolute;
  top: 50%;
  z-index: 4;
  width: 46px;
  height: 46px;
  margin: -23px 0 0 -23px;
  border-radius: 50%;
  border: 2px solid var(--white);
  background: var(--orange);
  color: var(--black);
  cursor: ew-resize;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  touch-action: none; /* the grip owns its gestures; the page scrolls everywhere else */
  padding: 0;
}
.ba-slider__handle svg { width: 22px; height: 22px; pointer-events: none; }
.ba-slider__hint {
  text-align: center;
  color: var(--muted);
  font-size: .92rem;
  margin: 12px 0 0;
}

/* ---------- The arrival: full-bleed verified before/after (home hero) ----------
   The whole stage is the control; images never intercept; copy is
   pointer-transparent except its CTAs. No-JS ships the 62/38 split. */
.arr { position: relative; display: block; }
.arr__stage {
  position: relative;
  width: 100%;
  /* the band's real height at this width, in every mode: the ticker is 64
     and the reduced-motion stack keeps the 120 this literal used to hold */
  height: calc(100svh - var(--header-h) - var(--trust-h));
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none;
  touch-action: pan-y;
  cursor: ew-resize;
}
.arr__stage img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  -webkit-user-drag: none;
  pointer-events: none;
}
.arr__after { clip-path: inset(0 0 0 62%); }
.arr__line {
  position: absolute; top: 0; bottom: 0; left: 62%;
  width: 3px; margin-left: -1.5px;
  background: var(--white);
  box-shadow: 0 0 8px rgba(2, 2, 2, .6);
  z-index: 3; pointer-events: none;
}
.arr__grip {
  position: absolute; top: 30%; left: 62%;
  z-index: 6;
  width: 46px; height: 46px; margin: -23px 0 0 -23px;
  border-radius: 50%;
  border: 2px solid var(--white);
  background: var(--orange); color: var(--black);
  cursor: ew-resize;
  display: inline-flex; align-items: center; justify-content: center;
  touch-action: none;
  padding: 0;
}
.arr__grip::before {
  content: ""; position: absolute; top: -30vh; bottom: -50vh; left: -14px; right: -14px;
}
.arr__grip svg { width: 22px; height: 22px; pointer-events: none; }
.arr__badge {
  position: absolute; top: 14px; z-index: 4;
  font-family: var(--font-head); font-weight: 700; font-size: .92rem;
  text-transform: uppercase; letter-spacing: .08em;
  padding: 5px 14px; border-radius: 999px; pointer-events: none;
}
.arr__badge--b { left: 14px; background: var(--ink); color: var(--white); }
/* both labels are the same kind of element, so they look the same
   (operator 2026-08-20: the orange AFTER badge read as a different control) */
.arr__badge--a { right: 14px; background: var(--ink); color: var(--white); }
.arr__copy {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 5;
  padding: clamp(18px, 3vw, 40px) clamp(16px, 4vw, 28px);
  padding-top: 90px;
  background: linear-gradient(0deg, rgba(2, 2, 2, .9) 30%, rgba(2, 2, 2, .55) 70%, transparent 100%);
  pointer-events: none;
}
.arr__copy > * { max-width: 620px; }
.arr__copy h1 {
  /* the arrival owns its colours: integration dropped the .hero class (its
     flex rule) and silently lost .hero h1's white with it (regression
     caught by the operator 2026-08-20) */
  color: var(--white);
  font-size: clamp(2rem, 4.2vw, 3rem);
  margin-bottom: .2em;
}
.arr__sub { color: var(--on-dark-muted); margin: 0 0 6px; }
.arr__copy .hero__ctas { margin-top: 14px; pointer-events: auto; }
.arr__copy .hero__badge { pointer-events: auto; }
@media (max-width: 1020px) {
  .arr__copy h1 { font-size: clamp(1.7rem, 6.4vw, 2.2rem); }
}
