/* ============================================================================
   Chinook Exteriors — "Section Cut"
   ----------------------------------------------------------------------------
   Design language: an architectural section drawing. Hard orange rules mark
   structure, 45° hatching stands in for cut material, geometry stays square
   (contractors build square things), and shadows are crisp offsets rather than
   soft blurs — like ink on a spec sheet, not a SaaS card.

   Type: Archivo (rigid industrial display) over Hanken Grotesk (warm humanist
   body). Service pages run 1,500–2,400 words, so body legibility outranks
   display flourish.

   Palette is scraped from the live site: Chinook orange #f37f06 on slate
   #2d3940, laid on warm limestone paper rather than clinical white.
   ========================================================================= */

/* ---------------------------------------------------------------- tokens -- */
:root {
  --orange:       #f37f06;
  --orange-deep:  #d46a00;
  --orange-tint:  #fdf0e0;
  --orange-glow:  rgba(243, 127, 6, .22);

  --ink:          #2d3940;
  --ink-deep:     #1b2429;
  --ink-muted:    #63737d;
  --ink-faint:    #91a0a9;

  --paper:        #faf8f5;
  --paper-alt:    #f1eee9;
  --white:        #ffffff;
  --steel:        #ded8d0;
  --steel-soft:   #ebe6df;

  --success:      #1f9c6a;
  --warning:      #cf2e2e;

  --font-display: 'Archivo', 'Arial Narrow', sans-serif;
  --font-body:    'Hanken Grotesk', -apple-system, sans-serif;

  /* Section-cut hatching — the signature texture. */
  --hatch: repeating-linear-gradient(45deg,
            transparent 0 6px, rgba(45, 57, 64, .045) 6px 7px);
  --hatch-light: repeating-linear-gradient(45deg,
            transparent 0 6px, rgba(255, 255, 255, .05) 6px 7px);

  /* Crisp offset shadows — ink on paper, never a blurry halo. */
  --lift:      4px 4px 0 rgba(45, 57, 64, .07);
  --lift-lg:   8px 8px 0 rgba(45, 57, 64, .09);
  --lift-hard: 6px 6px 0 var(--ink);

  --radius:    3px;
  --rule:      3px;

  --wrap:      1200px;
  --gutter:    clamp(1.1rem, 4vw, 2.5rem);

  --ease:      cubic-bezier(.2, .7, .3, 1);
  --dur:       .22s;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* The header is position:sticky (72–96px). Without this, jumping to an in-page
     anchor (#main, #private-feedback) scrolls the target UNDER the header. Web
     Interface Guidelines: scroll-margin on heading anchors — done here as
     scroll-padding on the scroll container so it covers every anchor at once. */
  scroll-padding-top: 6rem;
  /* Light-only brand. Declaring it fixes native control + scrollbar rendering
     (e.g. the country <select>, date pickers) on OS dark mode. */
  color-scheme: light;
}
/* WIG: honour prefers-reduced-motion for smooth-scroll too, not just keyframes. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* WIG mobile-interaction defaults on everything interactive:
   - touch-action: manipulation removes the 300ms double-tap-zoom delay on tap.
   - tap-highlight set intentionally to transparent — the design supplies its own
     :active states, so the browser's default grey flash is redundant. */
a, button, input, select, textarea, summary, label, [role="button"] {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.72;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }
svg { flex-shrink: 0; }

a { color: var(--orange-deep); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { color: var(--ink); }

/* Focus: a hard orange bracket, never a soft glow. */
:focus-visible {
  outline: 3px solid var(--orange);
  outline-offset: 2px;
  border-radius: 1px;
}
:focus:not(:focus-visible) { outline: none; }

::selection { background: var(--orange); color: #fff; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--ink-deep); color: #fff;
  padding: .85rem 1.4rem; font-weight: 700; font-family: var(--font-display);
}
.skip-link:focus { left: 0; }

/* ------------------------------------------------------------ typography -- */
h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  color: var(--ink);
  line-height: 1.08;
  letter-spacing: -.02em;
  margin: 0 0 .6em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.3rem, 5.4vw, 4rem); font-weight: 800; }
h2 { font-size: clamp(1.75rem, 3.4vw, 2.6rem); font-weight: 700; }
h3 { font-size: clamp(1.2rem, 2vw, 1.45rem); font-weight: 700; letter-spacing: -.01em; }
h4 { font-size: 1.05rem; font-weight: 700; letter-spacing: 0; }

p { margin: 0 0 1.15rem; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

strong, b { font-weight: 700; color: var(--ink); }

/* Eyebrow — a small-caps label sitting on its own orange rule.
   NOTE: alignment is set EXPLICITLY (never inherited). An inline-block child
   follows its PARENT's text-align, which is how centred eyebrows end up
   stranded left. Audit sub-check 27a. */
.eyebrow {
  display: inline-block;
  text-align: left;
  font-family: var(--font-display);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--orange-deep);
  padding-bottom: .5rem;
  margin-bottom: 1rem;
  border-bottom: var(--rule) solid var(--orange);
}

ul, ol { margin: 0 0 1.3rem; padding-left: 1.15rem; }
li { margin-bottom: .55rem; }
li::marker { color: var(--orange); font-weight: 700; }

blockquote {
  margin: 2rem 0;
  padding: 1.4rem 0 1.4rem 1.6rem;
  border-left: var(--rule) solid var(--orange);
  font-size: 1.15rem;
  font-style: italic;
  color: var(--ink);
}

hr { border: 0; border-top: 1px solid var(--steel); margin: 2.5rem 0; }

/* ----------------------------------------------------------------- table -- */
/* Wide content scrolls inside its own box; the page body never scrolls sideways. */
.table-wrap {
  overflow-x: auto;
  margin: 2rem 0;
  border: 1px solid var(--steel);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  background: var(--white);
}
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .96rem;
  min-width: 34rem;
}
.data-table th,
.data-table td {
  padding: .85rem 1.1rem;
  text-align: left;
  border-bottom: 1px solid var(--steel-soft);
  vertical-align: top;
}
.data-table thead th,
.data-table tr:first-child th {
  font-family: var(--font-display);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #fff;
  background: var(--ink-deep);
  border-bottom: var(--rule) solid var(--orange);
  white-space: nowrap;
}
.data-table tbody tr:last-child td { border-bottom: 0; }
.data-table tbody tr:nth-child(even) { background: var(--paper); }
.data-table td:first-child { font-weight: 600; color: var(--ink); }

/* ---------------------------------------------------------------- layout -- */
.container {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
/* For single-column content (a standalone form) that would read badly at full
   measure. */
.container--narrow { max-width: 720px; }

.section { padding: clamp(3.5rem, 7vw, 6rem) 0; position: relative; }
.section--tight { padding: clamp(2.2rem, 4vw, 3.2rem) 0; }

/* Alt sections carry the hatch — the "cut material" read. */
.section--alt {
  background-color: var(--paper-alt);
  background-image: var(--hatch);
  border-top: 1px solid var(--steel);
  border-bottom: 1px solid var(--steel);
}

.section--quote { background: var(--ink-deep); color: var(--paper); }
.section--quote h2, .section--quote h3 { color: #fff; }

.sec-head { max-width: 62ch; margin-bottom: 2.8rem; }

.two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
}
.two-col--reverse > :first-child { order: 2; }

/* Media slot. The 4:3 ratio is deliberate: the scraped WP image pool is
   overwhelmingly ~1.6:1, which lands inside audit sub-check 20's tolerance.
   Changing this ratio without re-checking the pool will start cropping images
   to slivers. */
.two-col-media {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--steel-soft);
  box-shadow: var(--lift-lg);
}
.two-col-media img { width: 100%; height: 100%; object-fit: cover; }
/* Orange corner bracket — the section-cut callout mark. */
.two-col-media::after {
  content: "";
  position: absolute; left: 0; bottom: 0;
  width: 44px; height: var(--rule);
  background: var(--orange);
}

.prose { max-width: 72ch; }
.prose h2 { margin-top: 2.6rem; }
.prose h3 { margin-top: 2rem; }
.prose__figure { margin: 2rem 0; }
.prose__figure img { border-radius: var(--radius); box-shadow: var(--lift); }

/* --------------------------------------------------------------- buttons -- */
.btn {
  --btn-bg: var(--orange);
  --btn-fg: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 48px;                       /* tap target ≥ 44px */
  padding: .85rem 1.6rem;
  font-family: var(--font-display);
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-decoration: none;
  color: var(--btn-fg);
  background: var(--btn-bg);
  border: 2px solid var(--btn-bg);
  border-radius: var(--radius);
  cursor: pointer;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.btn:hover {
  color: var(--btn-fg);
  transform: translate(-2px, -2px);
  box-shadow: 4px 4px 0 var(--ink);
}
.btn:active { transform: translate(0, 0); box-shadow: none; }

.btn-primary, .btn--primary { --btn-bg: var(--orange); --btn-fg: #fff; }
.btn-primary:hover, .btn--primary:hover { background: var(--orange-deep); border-color: var(--orange-deep); }

.btn-ghost {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  border-color: var(--ink);
}
.btn-ghost:hover { background: var(--ink); color: #fff; box-shadow: 4px 4px 0 var(--orange); }

.btn-on-dark {
  --btn-bg: #fff;
  --btn-fg: var(--ink-deep);
  border-color: #fff;
}
.btn-on-dark:hover { box-shadow: 4px 4px 0 var(--orange); color: var(--ink-deep); }

.btn--lg { min-height: 56px; padding: 1.05rem 2.1rem; font-size: 1.02rem; }
.btn--full { width: 100%; }
.btn-nav { padding: .7rem 1.15rem; min-height: 44px; }

.btn-row { display: flex; flex-wrap: wrap; gap: .85rem; }

/* ---------------------------------------------------------------- topbar -- */
.topbar {
  background: #131a1e;
  color: var(--ink-faint);
  font-size: .84rem;
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.topbar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 42px;
}
.topbar-info { display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; }
.tb-item { display: inline-flex; align-items: center; gap: .45rem; color: var(--paper); }
.tb-item svg { color: var(--orange); }
.tb-item a { color: inherit; text-decoration: none; }
.tb-item a:hover { color: var(--orange); text-decoration: underline; }

.topbar-social { display: flex; gap: .35rem; }
.tb-social {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px;
  color: var(--paper);
  border-radius: var(--radius);
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.tb-social:hover { color: var(--orange); background: rgba(255, 255, 255, .08); }

/* ---------------------------------------------------------------- header -- */
/* DARK header — not a style whim. The client's only logo asset is white-on-
   transparent with the wordmark knocked out, so on a light header it renders as
   a ghost. Rather than ask for a dark-ink logo variant (a round-trip, and the
   brand may not have one), the header carries the dark plate the mark was drawn
   for. It also lets the orange rule read as a structural edge. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--ink-deep);
  background-image: var(--hatch-light);
  border-bottom: var(--rule) solid var(--orange);
  box-shadow: 0 2px 12px rgba(27, 36, 41, .16);
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 92px;
}
.brand { display: inline-flex; align-items: center; text-decoration: none; flex-shrink: 0; }
/* The client's logo has the phone number baked into the artwork, so it needs more
   height than a wordmark would to stay legible. */
.brand-logo { height: 74px; width: auto; }
.brand-logo--footer { height: 88px; width: auto; }

.main-nav {
  display: flex;
  align-items: center;
  gap: .25rem;
  margin-left: auto;
}
.main-nav > a,
.services-toggle {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  min-height: 44px;
  padding: .55rem .8rem;
  font-family: var(--font-display);
  font-size: .95rem;
  font-weight: 600;
  color: var(--paper);
  text-decoration: none;
  background: none;
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  position: relative;
  transition: color var(--dur) var(--ease);
}
/* Active/hover marker: the orange rule again, drawn under the label. */
.main-nav > a::after,
.services-toggle::after {
  content: "";
  position: absolute;
  left: .8rem; right: .8rem; bottom: .25rem;
  height: var(--rule);
  background: var(--orange);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.main-nav > a:hover, .services-toggle:hover,
.main-nav > a.active, .services-toggle.active { color: var(--orange); }
.main-nav > a:hover::after, .services-toggle:hover::after,
.main-nav > a.active::after, .services-toggle.active::after { transform: scaleX(1); }

/* The Free Estimate CTA. `.main-nav > a` above resets background/border for the
   plain nav links, and at 0,1,1 it OUT-SPECIFIES `.btn` (0,1,0) — which is why
   the CTA was rendering as bare text with no box. Restore the button plate here,
   at 0,2,1, so it wins. */
.main-nav > a.btn-nav {
  margin-left: .5rem;
  padding: .7rem 1.2rem;
  font-weight: 700;
  color: #fff;
  background: var(--orange);
  border: 2px solid var(--orange);
  border-radius: var(--radius);
}
.main-nav > a.btn-nav::after { display: none; }   /* no underline rule; it has a box */
.main-nav > a.btn-nav:hover {
  color: #fff;
  background: var(--orange-deep);
  border-color: var(--orange-deep);
  transform: translate(-2px, -2px);
  /* Hard offset shadow, as elsewhere — but keyed to the dark header plate, where
     the usual --ink shadow would be invisible. */
  box-shadow: 4px 4px 0 rgba(0, 0, 0, .55);
}
.main-nav > a.btn-nav:active { transform: translate(0, 0); box-shadow: none; }

.nav-phone {
  display: inline-flex; align-items: center; gap: .4rem;
  min-height: 44px; padding: .55rem .8rem;
  margin-left: .4rem;
  font-family: var(--font-display);
  font-weight: 700;
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
}
.nav-phone svg { color: var(--orange); }
.nav-phone:hover { color: var(--orange); }

.chev { font-size: .8em; line-height: 1; transition: transform var(--dur) var(--ease); }

/* ------------------------------------------- services cascade (desktop) -- */
.has-dropdown { position: relative; }

.dropdown {
  position: absolute;
  top: calc(100% + 10px);          /* deliberate visual gap — see the bridge below */
  left: 0;
  z-index: 120;
  min-width: 260px;
  padding: .5rem;
  background: var(--white);
  border: 1px solid var(--steel);
  border-top: var(--rule) solid var(--orange);
  border-radius: var(--radius);
  box-shadow: var(--lift-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
              visibility var(--dur);
}

/* ▲ HOVER BRIDGE — MANDATORY (audit sub-check 21).
   The panel sits 10px below its toggle. Without a hoverable element spanning
   that dead gap, the cursor leaves :hover on the way down and the menu snaps
   shut — the classic "I have to click Services" bug. This transparent
   pseudo-element keeps the cursor inside the hover region the whole way. */
.dropdown::before {
  content: "";
  position: absolute;
  top: calc(-10px - var(--rule));
  left: 0;
  right: 0;
  height: calc(10px + var(--rule));
}

.has-dropdown:hover > .dropdown,
.has-dropdown:focus-within > .dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.has-dropdown:hover > .services-toggle .chev,
.has-dropdown:focus-within > .services-toggle .chev { transform: rotate(180deg); }

.dropdown-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  min-height: 44px;
  padding: .6rem .85rem;
  font-family: var(--font-display);
  font-size: .95rem;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  border-radius: var(--radius);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.dropdown-item:hover,
.has-submenu:hover > .dropdown-item,
.has-submenu:focus-within > .dropdown-item {
  background: var(--orange-tint);
  color: var(--orange-deep);
}
.dropdown-item--parent .chev { color: var(--ink-faint); }
.has-submenu:hover > .dropdown-item--parent .chev { color: var(--orange); }

/* Flyout panel. It OVERLAPS its parent by 4px, so no bridge is needed here —
   there is no dead gap to cross. */
.has-submenu { position: relative; }
.submenu {
  position: absolute;
  top: -.5rem;
  left: calc(100% - 4px);
  z-index: 130;
  min-width: 268px;
  padding: .5rem;
  background: var(--white);
  border: 1px solid var(--steel);
  border-left: var(--rule) solid var(--orange);
  border-radius: var(--radius);
  box-shadow: var(--lift-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateX(-6px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
              visibility var(--dur);
}
.has-submenu:hover > .submenu,
.has-submenu:focus-within > .submenu {
  opacity: 1;
  visibility: visible;
  transform: translateX(0);
}
.submenu a {
  display: block;
  min-height: 44px;
  padding: .6rem .85rem;
  font-size: .93rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  border-radius: var(--radius);
  line-height: 1.5;
}
.submenu a:hover { background: var(--orange-tint); color: var(--orange-deep); }

.submenu-overview {
  font-family: var(--font-display);
  font-weight: 700 !important;
  color: var(--orange-deep) !important;
  border-bottom: 1px solid var(--steel-soft);
  margin-bottom: .25rem;
  border-radius: var(--radius) var(--radius) 0 0 !important;
}

.menu-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 48px; height: 48px;
  padding: 0 11px;
  background: none;
  border: 1px solid rgba(255,255,255,.28);
  border-radius: var(--radius);
  cursor: pointer;
}
.menu-toggle span {
  display: block; height: 2px; width: 100%;
  background: var(--paper);
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ------------------------------------------------------------------ hero -- */
.hero {
  position: relative;
  overflow: hidden;
  padding: clamp(3rem, 6vw, 5.5rem) 0 clamp(3.5rem, 7vw, 6rem);
  background-color: var(--paper);
  background-image: var(--hatch);
  border-bottom: 1px solid var(--steel);
}
.hero__grid {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  position: relative;
  z-index: 2;
}
.hero__content { max-width: 34rem; }
.hero h1 { margin-bottom: 1rem; }
.hero__sub {
  font-size: clamp(1.05rem, 1.6vw, 1.22rem);
  color: var(--ink-muted);
  margin-bottom: 1.8rem;
  max-width: 32rem;
}
.hero__tag { /* retained for legacy markup; suppressed — see audit sub-check 13 */
  display: none;
}
.hero__actions { display: flex; flex-wrap: wrap; gap: .85rem; align-items: center; }
.hero__phone {
  display: inline-flex; align-items: center; gap: .5rem;
  min-height: 48px;
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
}
.hero__phone svg { color: var(--orange); }
.hero__phone:hover { color: var(--orange-deep); }

/* The hero photo sits proud of an orange outline block — a spec-sheet callout. */
.hero__visual { position: relative; }
.hero__photo {
  position: relative;
  z-index: 2;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--steel-soft);
  box-shadow: var(--lift-lg);
}
.hero__photo img { width: 100%; height: 100%; object-fit: cover; }
.hero__visual::before {
  content: "";
  position: absolute;
  inset: 18px -18px -18px 18px;
  border: 2px solid var(--orange);
  border-radius: var(--radius);
  z-index: 1;
}

/* Floating credential chips. */
.hero__chip {
  position: absolute;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .7rem 1rem;
  background: var(--white);
  border: 1px solid var(--steel);
  border-left: var(--rule) solid var(--orange);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  font-family: var(--font-display);
  font-size: .82rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--ink);
}
.hero__chip--years { left: -14px; bottom: 34px; }
.hero__badge { display: flex; flex-direction: column; }
.hero__badge-text { font-size: .72rem; font-weight: 600; color: var(--ink-muted); letter-spacing: .04em; }
.num { font-family: var(--font-display); font-size: 1.5rem; font-weight: 800; color: var(--orange-deep); line-height: 1; }
/* "Over" is a flex sibling of the numeral (.hero__chip is an inline-flex row), so
   the chip reads as one phrase: OVER · 15 · years in Calgary. Kept small and
   muted deliberately — it qualifies the number without competing with it, since
   the 15 is what the eye should land on. */
.chip-pre {
  font-family: var(--font-display);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-muted);
  line-height: 1;
}

/* Legacy blob hooks from the shared shell — neutralised, the hatch does this job. */
.hero__blob, .hero__blob--1, .hero__blob--2 { display: none; }

/* ----------------------------------------------------------------- tiles -- */
.tiles { background: var(--ink-deep); background-image: var(--hatch-light); color: var(--paper); }
.tiles__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: rgba(255,255,255,.12); }
.tile__link {
  display: flex; align-items: center; gap: 1rem;
  padding: 1.6rem 1.4rem;
  background: var(--ink-deep);
  color: var(--paper);
  text-decoration: none;
  transition: background var(--dur) var(--ease);
}
.tile__link:hover { background: #232e34; color: #fff; }
.tile__link strong { color: #fff; font-family: var(--font-display); font-size: 1rem; }
.tiles .hero__badge-text { color: var(--ink-faint); }
.tile__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex-shrink: 0;
  color: var(--orange);
  background: rgba(243, 127, 6, .12);
  border-radius: var(--radius);
}

/* ----------------------------------------------------------------- cards -- */
.svc-grid, .subsvc-grid, .service-grid, .post-grid, .team-grid, .contact-grid {
  display: grid;
  gap: 1.5rem;
}
.svc-grid, .service-grid { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.subsvc-grid { grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); }
.post-grid   { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.team-grid   { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.contact-grid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }

/* One card recipe, shared. The orange top rule wipes in on hover. */
.svc-card, .subsvc-card, .post-card, .team-card, .contact-card, .aside-card, .review-widget-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 1.7rem 1.5rem;
  background: var(--white);
  border: 1px solid var(--steel);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.svc-card::before, .subsvc-card::before, .post-card::before {
  content: "";
  position: absolute; top: -1px; left: -1px; right: -1px;
  height: var(--rule);
  background: var(--orange);
  border-radius: var(--radius) var(--radius) 0 0;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.svc-card:hover, .subsvc-card:hover, .post-card:hover {
  transform: translate(-3px, -3px);
  box-shadow: var(--lift-lg);
}
.svc-card:hover::before, .subsvc-card:hover::before,
.post-card:hover::before, .post-card:focus-within::before { transform: scaleX(1); }

.svc-card h3, .subsvc-card h3, .post-card h3 { margin-bottom: .55rem; }
/* The card IS the anchor (`<a class="svc-card">`), so the selector must be
   `a.svc-card`, not `.svc-card a` — the latter matches nothing and leaves the
   whole card underlined and link-coloured. The card is the affordance; the
   "Learn more →" line carries the visual cue. */
a.svc-card, a.subsvc-card, a.post-card, a.post-card__link {
  text-decoration: none;
  color: inherit;
}
a.svc-card:hover, a.subsvc-card:hover, a.post-card:hover { color: inherit; }
.svc-card h3, .subsvc-card h3, .post-card h3 { color: var(--ink); }
a.svc-card:hover h3, a.subsvc-card:hover h3, a.post-card:hover h3 { color: var(--orange-deep); }
.svc-card p, .subsvc-card p { color: var(--ink-muted); font-size: .97rem; margin-bottom: 1.1rem; }

.svc-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px;
  margin-bottom: 1.1rem;
  color: var(--orange-deep);
  background: var(--orange-tint);
  border-radius: var(--radius);
}
.ico { color: var(--orange); flex-shrink: 0; }

/* "Learn more →" link, pinned to the card foot so uneven cards still align.
   Cards are NOT stretched to equal height (hardening Rule 8) — the grid lets
   them size to content; only the CTA is pinned. */
.svc-cta {
  margin-top: auto;
  display: inline-flex; align-items: center; gap: .35rem;
  font-family: var(--font-display);
  font-size: .9rem;
  font-weight: 700;
  color: var(--orange-deep);
  text-decoration: none;
}
.svc-cta:hover { gap: .6rem; color: var(--ink); }

.post-card__link { text-decoration: none; color: inherit; display: flex; flex-direction: column; height: 100%; }
.post-card__body { display: flex; flex-direction: column; flex: 1; }
.post-card--text { /* no thumbnail variant — keeps each hero photo on one page only */ }

.check-list { list-style: none; padding: 0; }
.check-list li {
  position: relative;
  padding-left: 1.7rem;
  margin-bottom: .7rem;
}
.check-list li::before {
  content: "";
  position: absolute; left: 0; top: .58em;
  width: 10px; height: 10px;
  background: var(--orange);
  border-radius: 1px;
}

/* --------------------------------------- feature cards (Divi blurb runs) -- */
/* Divi blurbs carry the substance of every page — the "why choose us" points,
   the trust badges, the process steps. They must read as CARDS. Rendering them
   as paragraphs is what turned the first homepage into a long grey list. */
.feat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
  gap: 1.25rem;
  margin-top: 2.5rem;
  /* Cards size to content — NOT stretched to equal height (hardening Rule 8). */
  align-items: start;
}
.feat-card {
  position: relative;
  padding: 1.5rem 1.4rem;
  background: var(--white);
  border: 1px solid var(--steel);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.feat-card:hover {
  transform: translate(-3px, -3px);
  box-shadow: var(--lift-lg);
  border-color: var(--orange);
}
.feat-card h3 {
  font-size: 1.05rem;
  margin-bottom: .45rem;
  letter-spacing: -.005em;
}
/* .prose/.svc-prose wrappers add margin-top:2rem to every h3 — inside a grid card
   that shoves the heading a full 2rem BELOW the checkmark (they share a grid row),
   which is the "Temporary tarping" misalignment. Cards own their spacing, so zero
   it. Scoped via .feat-grid for specificity higher than .svc-prose h3 (source
   order alone wouldn't win). */
.feat-grid .feat-card h3 { margin-top: 0; }
.feat-card p {
  margin: 0;
  font-size: .95rem;
  color: var(--ink-muted);
  line-height: 1.62;
}
.feat-card__tick {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  font-size: .78rem;
  font-weight: 700;
  color: #fff;
  background: var(--orange);
  border-radius: 2px;
}
/* Checkmark cards lay out as [tick | content] on a grid, so the tick sits in the
   SAME row as the first line of copy — heading OR paragraph — and auto-aligns to
   it. This replaces an absolute tick with a fixed `top` that was calibrated to a
   paragraph and therefore sat low against the larger, tighter headings (the
   "Temporary tarping" box). Grid removes the per-text-size guesswork entirely. */
.feat-grid:not(.feat-grid--numbered):not(.feat-grid--plain) .feat-card {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: .8rem;
  align-items: start;
}
.feat-grid:not(.feat-grid--numbered):not(.feat-grid--plain) .feat-card__tick {
  grid-column: 1;
  grid-row: 1;
  margin-top: .06rem;   /* centres on a body first line (line-height 1.62) */
}
/* A heading-led card sets line-height 1.08 on the h3, so its text sits ~5px
   higher in the row than a paragraph would. Pull the tick up to match — measured,
   not guessed (Chrome getBoundingClientRect: text centre was 4.9px above tick). */
.feat-grid:not(.feat-grid--numbered):not(.feat-grid--plain) .feat-card:has(> h3) .feat-card__tick {
  margin-top: -.16rem;
}
.feat-grid:not(.feat-grid--numbered):not(.feat-grid--plain) .feat-card > :is(h3, p) {
  grid-column: 2;
}

/* Plain variant — informational card runs (cost factors), no checkmark, no gutter. */
.feat-grid--plain .feat-card { padding: 1.5rem 1.4rem; }
/* Numbered variant — process/step runs.
   The three elements stack vertically: number, rule, heading. Each needs real
   clearance — previously the 1.5rem-tall numeral (top 1.2rem, so its baseline sat
   at ~2.7rem) collided with the rule at 2.55rem, which in turn sat right on top of
   the heading. Spacing below is set so nothing touches: number occupies
   1.6–3.4rem, rule sits at 4.1rem, content starts at 5.1rem. */
/* Process steps are PARALLEL items — 01/02/03 of one sequence — so they read as a
   set only if the boxes match. This is a deliberate exception to the usual
   "don't stretch uneven cards to equal height" rule, which exists to stop
   unrelated cards being padded out to a ragged common height. Here equal height is
   the point. Only the numbered variant stretches; .feat-grid still sizes to
   content. */
.feat-grid--numbered { align-items: stretch; }
.feat-grid--numbered .feat-card {
  padding: 5.1rem 1.6rem 1.75rem;
  height: 100%;
}
.feat-card__num {
  position: absolute;
  left: 1.6rem;
  top: 1.6rem;
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 800;
  line-height: 1;
  color: var(--orange);
  letter-spacing: -.03em;
}
.feat-grid--numbered .feat-card::after {
  content: "";
  position: absolute;
  left: 1.6rem; right: 1.6rem; top: 4.1rem;
  height: 2px;
  background: var(--orange-tint);
}
.feat-grid--numbered .feat-card h3 { margin-bottom: .6rem; }

/* ---------------------------------------------------------- award marquee -- */
/* A continuously scrolling credential strip under the hero. The track carries the
   chip set TWICE and translates by exactly -50%, so the loop closes seamlessly on
   itself with no visible jump or reset. */
.award-marquee {
  padding: 0;
  overflow: hidden;
  border-top: 1px solid rgba(255, 255, 255, .08);
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.award-marquee__viewport {
  overflow: hidden;
  /* Fade the chips out at both edges so they enter and leave, rather than being
     abruptly clipped by the viewport wall. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.award-marquee__track {
  display: flex;
  align-items: stretch;
  width: max-content;
  animation: award-scroll 38s linear infinite;
}
/* Pause on hover/focus so a reader can actually finish a chip. */
.award-marquee:hover .award-marquee__track,
.award-marquee__track:focus-within { animation-play-state: paused; }

@keyframes award-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.award-chip {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-shrink: 0;
  padding: 1.35rem 2.25rem;
  background: var(--ink-deep);
  color: var(--paper);
  font-size: .93rem;
  line-height: 1.45;
  white-space: nowrap;
  border-right: 1px solid rgba(255, 255, 255, .12);
}
.award-chip__tick { color: var(--orange); font-size: 1.05rem; flex-shrink: 0; }

/* No motion: the strip must still be READABLE, not frozen mid-scroll with half a
   chip cut off. Drop the animation, drop the duplicate set, and lay the real chips
   out as a static centred row. */
@media (prefers-reduced-motion: reduce) {
  .award-marquee__viewport { -webkit-mask-image: none; mask-image: none; }
  .award-marquee__track {
    animation: none;
    width: auto;
    flex-wrap: wrap;
    justify-content: center;
  }
  .award-marquee__track .award-chip[aria-hidden="true"] { display: none; }
}

/* --------------------------------------------------- associations strip -- */
.assoc-strip {
  padding: clamp(2rem, 4vw, 3rem) 0;
  background: var(--white);
  border-top: 1px solid var(--steel);
  border-bottom: 1px solid var(--steel);
}
.assoc-strip__grid {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(1.5rem, 5vw, 3.5rem);
}
.assoc-card {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: .5rem;
  filter: grayscale(1);
  opacity: .68;
  transition: filter var(--dur) var(--ease), opacity var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
a.assoc-card:hover { filter: grayscale(0); opacity: 1; transform: translateY(-2px); }
.assoc-card img { object-fit: contain; }

/* Per-logo size tuning (audit sub-check 16d). Association marks have wildly
   different aspect ratios — a single object-fit rule renders the wide ones at
   half the visual weight of the square ones. Each modifier below is tuned so
   every badge reads at roughly equal visual AREA, not equal height. */
.assoc-card--hardie img   { max-height: 46px; max-width: 190px; }
.assoc-card--iko img      { max-height: 54px; max-width: 130px; }
.assoc-card--alurex img   { max-height: 44px; max-width: 165px; }
.assoc-card--bbb img      { max-height: 58px; max-width: 130px; }
.assoc-card--cca img      { max-height: 66px; max-width: 110px; }
.assoc-card--homestars img{ max-height: 50px; max-width: 165px; }

/* Text-mark fallback. The source site presents these credentials as text, and we
   will not fabricate third-party certification logos — so until the client
   supplies official badge artwork, they render as typographic marks. Styled to
   read as deliberate marks, not as "a logo failed to load". */
.assoc-card--text {
  filter: none;
  opacity: 1;
  padding: .85rem 1.2rem;
  background: var(--paper);
  border: 1px solid var(--steel);
  border-left: var(--rule) solid var(--orange);
  border-radius: var(--radius);
  text-decoration: none;
  min-height: 56px;
}
a.assoc-card--text:hover {
  background: var(--orange-tint);
  border-color: var(--steel);
  border-left-color: var(--orange-deep);
  transform: translate(-2px, -2px);
  box-shadow: var(--lift);
}
.assoc-mark {
  font-family: var(--font-display);
  font-size: .86rem;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--ink);
  text-align: center;
  line-height: 1.35;
  max-width: 18ch;
}
a.assoc-card--text:hover .assoc-mark { color: var(--orange-deep); }

/* Footer association list (text links, distinct from the logo strip). */
.footer-assoc { border-top: 1px solid rgba(255,255,255,.1); margin-top: 2.5rem; padding-top: 1.8rem; }
.assoc-h { color: var(--paper); margin-bottom: .8rem; }
.assoc-list { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: .6rem 1.6rem; }
.assoc-list a { color: var(--ink-faint); font-size: .88rem; text-decoration: none; }
.assoc-list a:hover { color: var(--orange); text-decoration: underline; }

/* ----------------------------------------------------------------- forms -- */
.ff-form {
  padding: clamp(1.6rem, 3vw, 2.2rem);
  background: var(--white);
  border: 1px solid var(--steel);
  border-top: var(--rule) solid var(--orange);
  border-radius: var(--radius);
  box-shadow: var(--lift-lg);
}
.ff-form__head { margin-bottom: 1.5rem; }
.ff-form__head h3 { margin-bottom: .35rem; }
.ff-form__head p { color: var(--ink-muted); font-size: .95rem; margin: 0; }

.ff-row { margin-bottom: 1.1rem; display: flex; flex-direction: column; }
.ff-row--split { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }

.ff-form label {
  font-family: var(--font-display);
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: .4rem;
}

.ff-form input,
.ff-form select,
.ff-form textarea {
  width: 100%;
  min-height: 48px;
  padding: .75rem .9rem;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--steel);
  border-radius: var(--radius);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.ff-form textarea { min-height: 130px; resize: vertical; line-height: 1.6; }
.ff-form input:focus,
.ff-form select:focus,
.ff-form textarea:focus {
  outline: none;
  background: var(--white);
  border-color: var(--orange);
  box-shadow: 0 0 0 3px var(--orange-glow);
}
.ff-form input::placeholder, .ff-form textarea::placeholder { color: var(--ink-faint); }
.ff-form input:user-invalid, .ff-form textarea:user-invalid { border-color: var(--warning); }

/* Required marker — colour alone never carries the meaning; the asterisk does,
   and every required input also has the native `required` attribute. */
.ff-req { color: var(--orange); margin-left: .15em; }

/* Address block. The source form groups these five under one "Address" label,
   so we keep them in a real <fieldset> rather than five loose rows. */
.ff-group {
  border: 1px solid var(--steel);
  border-radius: var(--radius);
  padding: 1.25rem 1.1rem .3rem;
  margin: 0 0 1.1rem;
  background: color-mix(in srgb, var(--paper) 55%, transparent);
}
.ff-group legend {
  font-family: var(--font-display);
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink);
  padding: 0 .5rem;
  margin-left: -.25rem;
}

/* File input: the native control ignores most box styling, so style the button
   half via ::file-selector-button and let the field itself sit flush. */
.ff-form input[type="file"] {
  padding: .55rem .6rem;
  cursor: pointer;
  font-size: .95rem;
  color: var(--ink-muted);
}
.ff-form input[type="file"]::file-selector-button {
  font-family: var(--font-display);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--steel);
  border-radius: var(--radius);
  padding: .55rem .9rem;
  margin-right: .85rem;
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
.ff-form input[type="file"]::file-selector-button:hover {
  background: var(--orange);
  border-color: var(--orange);
  color: var(--white);
}

.ff-hint {
  margin: .45rem 0 0;
  font-size: .84rem;
  line-height: 1.45;
  color: var(--ink-muted);
}

/* Honeypot. Deliberately NOT display:none — plenty of bots skip hidden inputs,
   and the whole point is that they fill it. Pushed off-screen instead, with
   aria-hidden + tabindex=-1 on the markup so no human (sighted, screen-reader or
   keyboard) can land on it. */
.hp-wrap {
  position: absolute !important;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.ff-turnstile { margin-bottom: 1.1rem; }

.ff-error {
  margin: 0 0 1rem;
  padding: .75rem .9rem;
  font-size: .9rem;
  line-height: 1.45;
  color: var(--ink);
  background: color-mix(in srgb, var(--warning) 10%, var(--white));
  border: 1px solid var(--warning);
  border-radius: var(--radius);
}
.ff-error[hidden] { display: none; }

.ff-actions { margin-top: 1.4rem; }
.ff-fineprint { margin-top: .9rem; font-size: .84rem; color: var(--ink-muted); }

.ff-success {
  padding: 1.75rem 1.5rem;
  border: 1px solid var(--line);
  border-left: 4px solid var(--brand, #f37f06);
  border-radius: 12px;
  background: var(--surface-2, #fff);
}
.ff-success h3 { margin: 0 0 .4rem; }
.ff-success p { margin: 0; color: var(--ink-muted); }

.contact-form-wrap { position: relative; }

/* ------------------------------------------------------------------- faq -- */
.faq-list { display: flex; flex-direction: column; gap: .75rem; max-width: 80ch; }
.faq {
  background: var(--white);
  border: 1px solid var(--steel);
  border-radius: var(--radius);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.faq[open] { border-color: var(--orange); box-shadow: var(--lift); }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 56px;
  padding: 1rem 1.3rem;
  font-family: var(--font-display);
  font-size: 1.03rem;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--orange);
  line-height: 1;
  flex-shrink: 0;
  transition: transform var(--dur) var(--ease);
}
.faq[open] summary::after { content: "\2212"; transform: rotate(180deg); }
.faq summary:hover { color: var(--orange-deep); }
.faq__body { padding: 0 1.3rem 1.3rem; color: var(--ink-muted); }
.faq__body p:last-child { margin-bottom: 0; }
.faq-inline { margin-top: 2rem; }

/* -------------------------------------------------------------- cta band -- */
/* The band is a BLOCK sitting inside .container, not a full-bleed section — so it
   needs its own padding on ALL FOUR sides (the previous `padding: Xrem 0` left the
   text flush against the dark box's left and right edges) AND its own vertical
   margin (its wrapper <section> carries no .section class, so the band was
   welded to the section above it and to the footer below). */
.cta-band, .cdcp-band {
  position: relative;
  overflow: hidden;
  margin: clamp(3.5rem, 7vw, 5.5rem) 0;
  padding: clamp(2.75rem, 5vw, 4rem) clamp(1.75rem, 4vw, 3.5rem);
  background: var(--ink-deep);
  background-image: var(--hatch-light);
  color: var(--paper);
  border-top: var(--rule) solid var(--orange);
  border-radius: var(--radius);
}
/* The band immediately before the footer still needs breathing room beneath it —
   collapsing margins would otherwise butt it straight against the footer edge. */
.cta-band:last-child, .cdcp-band:last-child { margin-bottom: clamp(3.5rem, 7vw, 5.5rem); }

.cta-band-inner, .cdcp-band__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  flex-wrap: wrap;
}
.cta-band h2, .cdcp-band h2 { color: #fff; margin-bottom: .5rem; max-width: 22ch; }
.cta-band p, .cdcp-band p { color: var(--ink-faint); margin: 0; max-width: 46ch; }
.cta-band .btn, .cdcp-band__cta { flex-shrink: 0; }

/* ---------------------------------------------------- service-area columns -- */
/* A run of "Calgary NW / [6 neighbourhoods]" pairs. Stacked full-width it ran to
   a screen and a half of mostly-empty page; flowed into columns it reads as the
   directory it actually is. */
.areas-flow {
  columns: 4;
  column-gap: clamp(1.5rem, 3vw, 2.5rem);
  margin-top: 2rem;
}
.areas-flow h3 {
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--orange-deep);
  margin: 0 0 .75rem;
  padding-bottom: .5rem;
  border-bottom: 2px solid var(--orange);
  break-after: avoid;          /* never strand a heading at the foot of a column */
}
.areas-flow ul {
  list-style: none;
  padding: 0;
  margin: 0 0 1.9rem;
  break-inside: avoid;         /* keep a quadrant's list intact in one column */
}
.areas-flow li {
  margin: 0 0 .4rem;
  font-size: .95rem;
  color: var(--ink-muted);
}
.areas-flow li::marker { content: none; }

@media (max-width: 900px) { .areas-flow { columns: 2; } }
@media (max-width: 520px) { .areas-flow { columns: 1; } }

/* ---------------------------------------------------------- service page -- */
/* ONE fixed template for every repeated page type (hardening / sub-check 27b):
   main column + sticky sidebar, so instances cannot drift in width by how much
   copy each happens to carry. */
.service-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 330px;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}
.service-main { min-width: 0; }
.svc-prose { max-width: 72ch; }
.svc-prose h2 { margin-top: 2.8rem; }
.svc-prose h2:first-child { margin-top: 0; }
.svc-prose h3 { margin-top: 2rem; }
.svc-prose img { border-radius: var(--radius); box-shadow: var(--lift); margin: 1.8rem 0; }

.service-aside { position: sticky; top: 96px; display: flex; flex-direction: column; gap: 1.25rem; }

.aside-card { padding: 1.5rem 1.4rem; }
.aside-card__title {
  font-family: var(--font-display);
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--orange-deep);
  padding-bottom: .5rem;
  margin-bottom: 1rem;
  border-bottom: var(--rule) solid var(--orange);
  display: block;
  text-align: left;
}
.aside-card--cta { background: var(--ink-deep); background-image: var(--hatch-light); border-color: var(--ink-deep); color: var(--paper); }
.aside-card--cta .aside-card__title { color: var(--orange); }
.aside-cta__phone {
  display: block;
  font-family: var(--font-display);
  font-size: 1.45rem;
  font-weight: 800;
  color: #fff;
  text-decoration: none;
  margin-bottom: 1rem;
}
.aside-cta__phone:hover { color: var(--orange); }
.aside-cta__mark { color: var(--ink-faint); font-size: .88rem; }

.aside-nav { list-style: none; padding: 0; margin: 0; }
.aside-nav li { margin: 0; border-bottom: 1px solid var(--steel-soft); }
.aside-nav li:last-child { border-bottom: 0; }
.aside-nav a {
  display: block;
  padding: .7rem 0;
  min-height: 44px;
  font-size: .95rem;
  color: var(--ink);
  text-decoration: none;
}
.aside-nav a:hover { color: var(--orange-deep); padding-left: .35rem; transition: padding var(--dur) var(--ease); }

.aside-hours { list-style: none; padding: 0; margin: 0; font-size: .92rem; }
.aside-hours__row, .hours li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: .4rem 0;
  border-bottom: 1px solid var(--steel-soft);
}
.aside-hours__row:last-child, .hours li:last-child { border-bottom: 0; }
.aside-visit__addr { font-style: normal; color: var(--ink-muted); font-size: .95rem; }

.info-row { display: flex; align-items: flex-start; gap: .7rem; margin-bottom: .8rem; }
.info-row svg { margin-top: .3rem; color: var(--orange); }
.contact-link { color: var(--ink); text-decoration: none; font-weight: 600; }
.contact-link:hover { color: var(--orange-deep); text-decoration: underline; }

.map-embed {
  width: 100%;
  aspect-ratio: 4 / 3;
  border: 1px solid var(--steel);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  display: block;
}

.reviews-frame, .review-widget-card { padding: 0; overflow: hidden; }
.reviews-frame iframe, .review-widget-card iframe { width: 100%; border: 0; display: block; min-height: 420px; }
.review-cta { margin-top: 1.5rem; text-align: center; }

/* ---------------------------------------------------------------- crumbs -- */
.crumbs {
  padding: 1rem 0;
  font-size: .87rem;
  color: var(--ink-muted);
  border-bottom: 1px solid var(--steel);
}
.crumbs a { color: var(--ink-muted); text-decoration: none; }
.crumbs a:hover { color: var(--orange-deep); text-decoration: underline; }

/* --------------------------------------------------------------- article -- */
.article-hero { padding: clamp(2.5rem, 5vw, 4rem) 0 2rem; background-image: var(--hatch); border-bottom: 1px solid var(--steel); }
.article-hero__lead { font-size: 1.2rem; color: var(--ink-muted); max-width: 62ch; }
.article-hero__byline { font-size: .88rem; color: var(--ink-faint); margin-top: 1rem; }
.article-hero__img { margin-top: 2.5rem; border-radius: var(--radius); box-shadow: var(--lift-lg); }
.article-body { max-width: 72ch; margin-inline: auto; padding: clamp(2.5rem, 5vw, 4rem) 0; }
.article-body h2 { margin-top: 2.8rem; }

/* ------------------------------------------------------------------ team -- */
.team-card, .team-bio { text-align: left; }
.team-photo, .team-bio__photo {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: cover;
  border-radius: var(--radius);
  margin-bottom: 1rem;
}
.team-bio__monogram {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1 / 1;
  background: var(--orange-tint);
  color: var(--orange-deep);
  font-family: var(--font-display);
  font-size: 2.6rem;
  font-weight: 800;
  border-radius: var(--radius);
  margin-bottom: 1rem;
}
.team-name, .team-bio__name { font-family: var(--font-display); font-weight: 700; margin-bottom: .2rem; }
.team-role, .team-bio__role { color: var(--orange-deep); font-size: .88rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
.team-bios { display: flex; flex-direction: column; gap: 2.5rem; }
.team-bio__fun { color: var(--ink-muted); font-size: .95rem; }

/* ---------------------------------------------------------------- footer -- */
.site-footer {
  background: var(--ink-deep);
  background-image: var(--hatch-light);
  color: var(--ink-faint);
  padding: clamp(3rem, 6vw, 4.5rem) 0 1.5rem;
  border-top: var(--rule) solid var(--orange);
  font-size: .95rem;
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1.3fr;
  gap: clamp(1.8rem, 4vw, 3rem);
}
.footer-brand .brand-logo--footer { opacity: .95; }
.footer-tagline { margin: 1.1rem 0 1.3rem; color: var(--ink-faint); max-width: 30ch; }

.site-footer h4 {
  color: #fff;
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding-bottom: .55rem;
  margin-bottom: 1.1rem;
  border-bottom: var(--rule) solid var(--orange);
  display: block;
  text-align: left;
}
.footer-hours-h { margin-top: 1.8rem; }

.footer-col ul, .footer-contact { list-style: none; padding: 0; margin: 0; }
.footer-col li { margin-bottom: .55rem; }
.footer-col a { color: var(--ink-faint); text-decoration: none; }
.footer-col a:hover { color: var(--orange); text-decoration: underline; }

.footer-contact li { display: flex; align-items: flex-start; gap: .6rem; margin-bottom: .8rem; }
.footer-contact svg { margin-top: .35rem; color: var(--orange); }

/* The light-plate defaults. .footer-contact and .time are reused OUTSIDE the
   footer (the contact-us "Visit us" panel), so the near-white treatment must be
   scoped to the dark footer plate — unscoped, it rendered white-on-cream and the
   phone, email and opening times were invisible on /contact-us/. */
.footer-contact a { color: var(--ink); text-decoration: none; font-weight: 600; }
.footer-contact a:hover { color: var(--orange-deep); text-decoration: underline; }

.hours { list-style: none; padding: 0; margin: 0; font-size: .9rem; }
.day { color: var(--ink-muted); }
.time { color: var(--ink); font-weight: 600; }

.site-footer .footer-contact a { color: var(--paper); font-weight: 400; }
.site-footer .footer-contact a:hover { color: var(--orange); text-decoration: none; }
.site-footer .hours li { border-bottom-color: rgba(255,255,255,.08); }
.site-footer .day { color: var(--ink-faint); }
.site-footer .time { color: var(--paper); }

.social { display: flex; gap: .5rem; }
.social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  color: var(--paper);
  border: 1px solid rgba(255,255,255,.16);
  border-radius: var(--radius);
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.social a:hover { color: var(--orange); border-color: var(--orange); background: rgba(243,127,6,.1); }

.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(255,255,255,.1);
  font-size: .86rem;
}
.footer-bottom-links a { color: var(--ink-faint); text-decoration: none; }
.footer-bottom-links a:hover { color: var(--orange); }

/* ------------------------------------------------------------- responsive -- */
@media (max-width: 1080px) {
  .service-layout { grid-template-columns: 1fr; }
  .service-aside { position: static; flex-direction: row; flex-wrap: wrap; }
  .service-aside > * { flex: 1 1 260px; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

/* Mobile nav. The cascade FLATTENS here — hover does not exist on touch, so
   every hub and child is rendered visible in a nested list (audit sub-check 7). */
@media (max-width: 980px) {
  .menu-toggle { display: flex; }

  .main-nav {
    position: fixed;
    inset: 0 0 0 auto;
    width: min(88vw, 380px);
    z-index: 200;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 1.25rem 1.25rem 3rem;
    margin: 0;
    background: var(--paper);
    border-left: var(--rule) solid var(--orange);
    box-shadow: -12px 0 40px rgba(27, 36, 41, .18);
    overflow-y: auto;
    /* WIG: contain scroll to the drawer — a flick past the end of the menu must
       not chain through to scroll the page body behind it. */
    overscroll-behavior: contain;
    transform: translateX(100%);
    visibility: hidden;
    transition: transform .3s var(--ease), visibility .3s;
  }
  .main-nav.active { transform: translateX(0); visibility: visible; }

  .main-nav > a, .services-toggle {
    width: 100%;
    justify-content: flex-start;
    padding: .85rem .5rem;
    border-bottom: 1px solid var(--steel-soft);
    border-radius: 0;
    /* The drawer is a LIGHT plate (background: var(--paper) above), but the
       desktop nav sits on the DARK header and colours its links var(--paper) to
       suit it. Inherited here, that painted near-white text on a near-white
       drawer: About Us / Services / Contact Us were rendering invisible. */
    color: var(--ink);
  }
  .main-nav > a:hover, .services-toggle:hover,
  .main-nav > a.active, .services-toggle.active { color: var(--orange-deep); }
  .nav-phone { color: var(--ink); }
  .main-nav > a::after, .services-toggle::after { display: none; }

  .has-dropdown { width: 100%; }

  /* Flatten: on desktop these are floating hover panels; in the drawer they
     become static, in-flow nested lists. */
  .dropdown, .submenu {
    position: static;
    opacity: 1;
    visibility: visible;
    transform: none;
    min-width: 0;
    width: 100%;
    padding: 0 0 0 .5rem;
    background: transparent;
    border: 0;
    border-left: 2px solid var(--steel);
    box-shadow: none;
    margin: .25rem 0 .5rem;
  }

  /* ...but COLLAPSED until tapped. Expanded-by-default meant opening the drawer
     dumped all 4 hubs and 11 subservices on the visitor at once, burying Contact
     Us and the CTA far below the fold. Tapping "Services" opens it.
     `.is-open` is set by main.js; on desktop the panel is hover/focus-driven and
     these rules do not apply. */
  .has-dropdown > .dropdown { display: none; }
  .has-dropdown.is-open > .dropdown { display: block; }

  /* The chevron is the only affordance signalling "this expands", so it must be
     visible here — it was previously hidden on mobile, leaving a Services row
     that looked like a plain link but behaved like a toggle. */
  .services-toggle .chev {
    display: inline-flex;
    margin-left: auto;              /* push to the far edge of the full-width row */
    font-size: 1rem;
  }
  .services-toggle[aria-expanded="true"] .chev { transform: rotate(180deg); }
  .dropdown::before { display: none; }   /* no gap to bridge when static */
  .submenu { border-left-color: var(--orange-tint); margin-left: .25rem; }
  .dropdown-item--parent .chev { display: none; }

  .nav-phone { justify-content: flex-start; padding: .85rem .5rem; margin: .5rem 0 0; }

  /* In the drawer the CTA is a full-width button, not a list row — so undo the
     row treatment (flush-left, square, hairline underneath) the reset applies. */
  .main-nav > a.btn-nav {
    width: 100%;
    margin: 1rem 0 0;
    justify-content: center;
    padding: .9rem 1.2rem;
    border: 2px solid var(--orange);
    border-radius: var(--radius);
  }

  .hero__grid { grid-template-columns: 1fr; }
  .hero__visual { order: -1; }
  .hero__visual::before { inset: 12px -12px -12px 12px; }
  .hero__chip--years { left: 8px; bottom: -14px; }
  .two-col, .two-col--reverse, .ff-row--split { grid-template-columns: 1fr; }
  .two-col--reverse > :first-child { order: 0; }
  .tiles__grid { grid-template-columns: 1fr; }
  .cta-band-inner, .cdcp-band__inner { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 640px) {
  .tb-hide-sm { display: none; }
  .topbar-inner { justify-content: center; }
  .footer-grid { grid-template-columns: 1fr; }
  .footer-bottom { flex-direction: column; align-items: flex-start; }
  .btn { width: 100%; }
  .btn-row .btn, .hero__actions .btn { width: 100%; }
  .assoc-strip__grid { gap: 1.5rem 2rem; }
}

/* ------------------------------------------------------------------ motion -- */
@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
.hero__content > *, .hero__visual {
  animation: rise .6s var(--ease) both;
}
.hero__content > *:nth-child(1) { animation-delay: .04s; }
.hero__content > *:nth-child(2) { animation-delay: .10s; }
.hero__content > *:nth-child(3) { animation-delay: .16s; }
.hero__content > *:nth-child(4) { animation-delay: .22s; }
.hero__visual                   { animation-delay: .18s; }

/* Off-ramp is mandatory — every transition and animation collapses to instant. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .btn:hover, .svc-card:hover, .subsvc-card:hover, .post-card:hover { transform: none; }
}

/* ------------------------------------------------------------------- print -- */
@media print {
  .topbar, .site-header, .cta-band, .site-footer, .menu-toggle, .map-embed { display: none; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .section { padding: 1rem 0; }
  a::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
}
