/* ===========================================================================
   Custom Fence Consulting - customfenceconsulting.co.nz
   ---------------------------------------------------------------------------
   Structure forked from the All Fencing Solutions build (the current fleet
   reference); the palette and type are this brand's own.

   THE PALETTE IS THE LOGO. Both values were counted off the pixels of the
   client's own CFC-consultinglogo.webp rather than sampled by eye - they are
   the two most common non-white colours in the file:

     sage      #a5b176   the panel, the fern and the "CONSULTING" rule
     charcoal  #3f3f3d   the "CUSTOM FENCE" wordmark and the fence marks

   #8a9a5b also appears as --sage-mid: that is the green Christine Ollerenshaw
   uses in her own email signature, so it is the brand's established mid tone.

   🔴 CONTRAST WAS MEASURED, NOT EYEBALLED (WCAG relative luminance):

     charcoal on white ............. 10.55:1   body text, headings
     charcoal on --band #f2f3ec ..... 9.45:1   text on the light band
     white on charcoal ............. 10.55:1   dark band, footer, buttons
     sage #a5b176 on charcoal ....... 4.60:1   accents ON DARK only
     charcoal on sage #a5b176 ....... 4.60:1   text on a sage panel
     --sage-dk #63703d on white ..... 5.36:1   links and accent TEXT on light

   The trap this avoids: the brand sage is a LIGHT green - 2.30:1 on white, and
   2.30:1 under white text. So it can never carry text either way against
   white. Sage is a graphic colour on light backgrounds and a text colour only
   on charcoal; anywhere accent text sits on white it uses --sage-dk.

   TYPE. The wordmark is a wide, high-contrast serif, so headings are a serif
   stack led by Georgia - present on effectively every Windows, macOS, iOS and
   Android device, which makes the display face free rather than a font
   download, and it echoes the logo instead of arguing with it. Body and UI
   stay on self-hosted Red Hat Text (SIL OFL) - a consultancy's pages are read,
   not skimmed, and a humanist sans is easier at 17px than a serif is.
   =========================================================================== */

/* ---------------------------------------------------------------- fonts
   Self-hosted latin subsets (SIL OFL 1.1) - no Google Fonts request, which
   would cost a DNS lookup, a connection and a redirect before a single glyph
   arrives. Otago clients are often on rural mobile data. */
@font-face {
  font-family: 'Red Hat Display';
  src: url('/assets/fonts/redhatdisplay-700-latin.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Red Hat Text';
  src: url('/assets/fonts/redhattext-400-latin.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Red Hat Text';
  src: url('/assets/fonts/redhattext-700-latin.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

/* ---------------------------------------------------------------- tokens */
:root {
  --ink:        #3f3f3d;   /* the logo's own charcoal - 10.55:1 on white */
  --ink-soft:   #55554f;
  --ink-mute:   #6d6d65;
  --dark:       #3f3f3d;   /* dark band AND footer - the same charcoal, not a second grey */
  --darker:     #2e2e2c;   /* the strip under the footer */
  --band:       #f2f3ec;   /* sage-tinted off-white; charcoal on it measures 9.45:1 */
  --band-2:     #e7eadb;   /* the deeper tint, for a band that needs to separate from --band */
  --line:       #dcded2;
  --white:      #ffffff;

  /* The brand greens. Read off the logo's pixels - see the header comment.
     --sage is LIGHT (2.30:1 on white), so it is a graphic colour on light
     backgrounds and a text colour only on charcoal. Accent TEXT on white uses
     --sage-dk, which measures 5.36:1. */
  --sage:       #a5b176;   /* logo panel, fern, "CONSULTING" rule */
  --sage-mid:   #8a9a5b;   /* the green from the client's own email signature */
  --sage-dk:    #63703d;   /* text-safe on white */

  --accent:     #63703d;
  --accent-dk:  #4f5a31;
  --accent-lt:  #a5b176;   /* the accent ON dark, where sage is legible */

  --btn-bg:     #3f3f3d;
  --btn-fg:     #ffffff;

  --wrap:       1180px;
  --gap:        clamp(20px, 3vw, 40px);
  --sec-y:      clamp(48px, 6vw, 78px);
  /* A consultancy, not a contractor. 3px reads as considered where a razor
     edge reads as industrial - and it matches the logo's soft panel corner. */
  --radius:     3px;
  --shadow:     0 6px 22px rgba(63,63,61,.14);

  /* Serif display to echo the wordmark; see the header comment on why this is
     a system stack rather than a fourth font download. */
  --font-head:  Georgia, 'Iowan Old Style', 'Palatino Linotype', 'Times New Roman', serif;
  --font-ui:    'Red Hat Display', 'Segoe UI', system-ui, sans-serif;
  --font-body:  'Red Hat Text', 'Segoe UI', system-ui, sans-serif;

  /* The ring-and-arrow glyph that sits inside every link button on the
     reference site, as a mask so it inherits the button's text colour and
     needs no markup change. One path, fill-rule evenodd: outer circle, inner
     circle punched out to leave a ring, then the arrowhead - which sits inside
     two boundaries plus its own, so it counts odd and fills. */
  --ico-tick:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.3 17.2 4 11.9l1.6-1.6 3.7 3.7L18.4 5l1.6 1.6Z'/%3E%3C/svg%3E");
  --ico-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 1.6A10.4 10.4 0 1 0 12 22.4 10.4 10.4 0 0 0 12 1.6Zm0 1.9a8.5 8.5 0 1 1 0 17 8.5 8.5 0 0 1 0-17Zm-1.9 4.2 6 4.3-6 4.3Z'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------- base */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* The header is sticky, so every in-page anchor - "Get a Quote" on every page,
     and the service links - would otherwise land with its heading hidden behind
     the header. One property fixes all of them. */
  scroll-padding-top: 96px;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  color: var(--ink);
  background: var(--white);
  overflow-x: hidden;
}

img, svg, video { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4 {
  font-family: var(--font-head);
  font-weight: 700;
  line-height: 1.2;
  /* Georgia at display size sets loose. A whisker of negative tracking pulls it
     back to the tight fit of the wordmark. */
  letter-spacing: -.012em;
  margin: 0 0 .55em;
  color: var(--ink);
  text-wrap: balance;
}

/* A conventional descending hierarchy here, unlike the reference build - that
   site inverts H1 and H2 because its client asked for a specific look. This one
   is an advisory site where the page heading IS the argument, so it leads.

   Display type scales to the CONTENT: build.mjs stamps data-len with the H1's
   character count, because a 24-character heading and a 90-character one cannot
   share a font size without one looking timid and the other pushing the hero
   CTA off the screen. */
h1 { font-size: clamp(2.05rem, 4.3vw, 3.15rem); }
h1[data-len="long"]  { font-size: clamp(1.8rem, 3.5vw, 2.6rem); }
h1[data-len="xlong"] { font-size: clamp(1.55rem, 2.9vw, 2.15rem); }

h2 { font-size: clamp(1.7rem, 3.2vw, 2.4rem); }
h3 { font-size: clamp(1.18rem, 1.8vw, 1.38rem); line-height: 1.35; }
h4 { font-size: 1.05rem; line-height: 1.4; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

/* Black links, underlined on hover only - exactly the reference's rule. */
a { color: var(--ink); text-decoration: none; }
a:hover, a:focus-visible { color: var(--ink); text-decoration: underline; }

strong { font-weight: 700; }

:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
}
/* A black focus ring is invisible on the dark bands, the hero and the footer.
   Same rule, inverted, wherever the background is dark. */
.sec--dark :focus-visible,
.hero :focus-visible,
.trust :focus-visible,
.ftr :focus-visible,
.faq :focus-visible,
.form :focus-visible { outline-color: #fff; }

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 32px);
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: #fff; padding: 12px 18px;
}
.skip:focus { left: 8px; top: 8px; }

/* The reference has no eyebrow labels at all - a section is just its big H2.
   These are kept because they carry keyword context for a crawler, but they are
   muted to a quiet grey so they read as a kicker rather than the flash of brand
   colour that made the first build look like a different site. */
.eyebrow {
  display: block;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: .76rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: .8em;
}
.sec--dark .eyebrow, .faq-band .eyebrow { color: rgba(255,255,255,.66); }

/* ---------------------------------------------------------------- buttons
   Components must beat prose. `.prose a` is (0,1,1) and `.btn` is (0,1,0), so
   without the :not() scoping further down, a body-link colour rule silently
   wins over a button's own colour and every CTA inside prose renders dark text
   on a dark button. That shipped once on prestigepainters at 1.00:1. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6em;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: .95rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1.2;
  padding: 15px 28px;
  border: 1px solid var(--btn-bg);
  border-radius: var(--radius);
  background: var(--btn-bg);
  color: var(--btn-fg);
  cursor: pointer;
  text-decoration: none;
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}
.btn:hover, .btn:focus-visible {
  background: var(--dark);
  border-color: var(--dark);
  color: #fff;
  text-decoration: none;
}

/* The ring-arrow rides on link buttons only. The reference's own SEND button
   is a plain label, and a "go somewhere" arrow on a form submit is a lie. */
a.btn::before {
  content: '';
  flex: 0 0 auto;
  width: 1.22em; height: 1.22em;
  background: currentColor;
  -webkit-mask: var(--ico-arrow) center / contain no-repeat;
          mask: var(--ico-arrow) center / contain no-repeat;
}
a.btn--bare::before { display: none; }

.btn--sm { padding: 11px 20px; font-size: .82rem; }
.btn--ghost {
  background: transparent;
  color: #fff;
  border-color: #fff;
}
.btn--ghost:hover, .btn--ghost:focus-visible {
  background: #fff; border-color: #fff; color: var(--ink);
}
.btn--light {
  background: #fff; border-color: #fff; color: var(--ink);
}
.btn--light:hover, .btn--light:focus-visible {
  background: var(--band); border-color: var(--band); color: var(--ink);
}
/* A white button on a WHITE section needs its own edge. Replaces the
   style="border-color:#1b1b1b" that was inlined on three of these. */
.btn--outline {
  background: #fff; border-color: var(--ink); color: var(--ink);
}
.btn--outline:hover, .btn--outline:focus-visible {
  background: var(--ink); border-color: var(--ink); color: #fff;
}

/* ---------------------------------------------------------------- header
   The reference header: white, sticky, logo hard left, the menu centred in
   UPPERCASE with a house glyph as its first item, and a single solid-black
   phone button hard right. It is tall on load and shrinks once the page
   scrolls - site.js flips [data-stuck] on, everything else is CSS.

   No border-bottom: the reference separates the bar from the page with a soft
   drop shadow, which is what lets the hero photo sit flush underneath it. */
.hdr {
  position: sticky;
  top: 0;
  z-index: 90;
  background: #fff;
  box-shadow: 0 1px 10px rgba(0,0,0,.16);
}
.hdr__in {
  display: flex;
  align-items: center;
  gap: clamp(12px, 2vw, 26px);
  min-height: 118px;
  transition: min-height .22s ease;
}
.hdr[data-stuck] .hdr__in { min-height: 82px; }
@media (prefers-reduced-motion: reduce) { .hdr__in { transition: none; } }

/* Brand lockup. Deliberately live text, not an image: the client has no vector
   logo on file and a re-typeset JPEG would look worse than this at every size.
   Swap in their real artwork when it arrives - only .brand needs to change. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  color: var(--ink);
  text-decoration: none;
  flex: 0 0 auto;
}
.brand:hover, .brand:focus-visible { text-decoration: none; color: var(--ink); }
.brand__mark { flex: 0 0 auto; width: 40px; height: 40px; transition: width .22s ease, height .22s ease; }
.hdr[data-stuck] .brand__mark { width: 34px; height: 34px; }
.brand__txt { display: block; line-height: 1; }
.brand__name {
  display: block;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.16rem;
  letter-spacing: .01em;
  text-transform: uppercase;
}
/* Mirrors the widely-tracked "NEW ERA ROOFING" wordmark under the reference's
   monogram. Grey, not a brand colour - the reference has none. */
.brand__sub {
  display: block;
  font-size: .64rem;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-top: 5px;
}

/* nowrap, not wrap. Six items plus a brand lockup and a phone-and-button group
   is a tight fit inside a 1220px container, and with flex-wrap:wrap the overflow
   is silent - "Contact" simply drops onto a second row and the header grows by
   60px. Below the breakpoint the burger takes over instead. */
.nav {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: clamp(10px, 1.4vw, 22px);
  margin-inline: auto;
}
/* Uppercase, REGULAR weight, no tracking - the reference menu is set in plain
   Red Hat Text at 16px and the restraint is a large part of its look. Bolding
   it, which the first build did, immediately reads as a different site. */
.nav a {
  font-size: .95rem;
  font-weight: 400;
  text-transform: uppercase;
  color: var(--ink);
  padding: 6px 2px;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.nav a:hover, .nav a:focus-visible {
  color: var(--ink);
  border-bottom-color: var(--ink);
  text-decoration: none;
}
.nav a[aria-current="page"] { border-bottom-color: var(--ink); }

/* The house glyph that opens the reference menu in place of a "Home" label. */
.nav__home { display: inline-flex; align-items: center; padding: 6px 2px; }
.nav__home svg { display: block; }

/* Services dropdown. Six services will not fit in a flat bar, and the reference
   site uses a dropdown too. Opens on hover AND on :focus-within, so it works
   with no JS and from the keyboard; the JS click handler exists only for touch
   devices, which never fire :hover reliably. */
.nav__drop { position: relative; display: flex; align-items: center; }
.nav__dropbtn {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-body);
  font-size: .95rem; font-weight: 400;
  text-transform: uppercase;
  color: var(--ink);
  background: none; border: 0;
  border-bottom: 2px solid transparent;
  padding: 6px 2px; cursor: pointer;
  white-space: nowrap;
}
.nav__dropbtn:hover, .nav__drop:focus-within .nav__dropbtn {
  color: var(--ink); border-bottom-color: var(--ink);
}
.nav__panel {
  position: absolute;
  top: 100%; left: 50%;
  transform: translateX(-50%);
  min-width: 278px;
  margin-top: 16px;
  padding: 8px 0;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  opacity: 0; visibility: hidden;
  transition: opacity .14s ease, visibility .14s ease;
}
/* Bridges the gap the margin opens up. Without it the pointer leaves .nav__drop
   on the way down to the panel, :hover drops and the menu closes under the
   cursor - which reads as a broken menu rather than a 16px offset. */
.nav__panel::before {
  content: ''; position: absolute; left: 0; right: 0; top: -18px; height: 18px;
}
.nav__drop:hover .nav__panel,
.nav__drop:focus-within .nav__panel,
.nav__drop[data-open] .nav__panel { opacity: 1; visibility: visible; }
.nav__panel a {
  display: block;
  padding: 9px 18px;
  border-bottom: 0;
  white-space: nowrap;
}
.nav__panel a:hover, .nav__panel a:focus-visible { background: #f5f5f5; border-bottom: 0; }
.nav__panel a[aria-current="page"] { border-bottom: 0; }

.hdr__cta { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }

/* The reference's one and only header CTA: a solid black block carrying a
   handset glyph and the number, with a soft shadow under it. It replaces the
   plain phone link plus separate quote button the first build used - two
   competing CTAs is the thing that made that header look generic.
   "Get a quote" is still one tap away: it leads every hero, it is the first
   item in the mobile menu, and the float bar carries it on every scroll. */
.hdr__phone {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: .01em;
  color: #fff;
  background: var(--btn-bg);
  padding: 15px 26px;
  box-shadow: 0 3px 10px rgba(0,0,0,.3);
  white-space: nowrap;
}
.hdr__phone:hover, .hdr__phone:focus-visible {
  color: #fff; background: var(--dark); text-decoration: none;
}
.hdr__phone svg { flex: 0 0 auto; }

.burger {
  display: none;
  width: 46px; height: 40px;
  padding: 9px 8px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
}
.burger span {
  display: block; height: 2px; background: var(--ink); border-radius: 2px;
}
.burger span + span { margin-top: 5px; }

.nav-m { display: none; border-top: 1px solid var(--line); background: #fff; padding: 8px 0 18px; }
.cnc-js .nav-m[data-open] { display: block; }
/* With JS off the desktop bar is still hidden below 1140px, so the mobile list
   has to be visible by default there or the site has no navigation at all. */
@media (max-width: 1140px) {
  html:not(.cnc-js) .nav-m { display: block; }
}
.nav-m a {
  display: block;
  padding: 12px clamp(18px, 4vw, 32px);
  font-weight: 700;
  color: var(--ink);
  border-bottom: 1px solid #f0f0f0;
}
.nav-m a:hover, .nav-m a:focus-visible { background: #f4f4f4; color: var(--ink); text-decoration: none; }
.nav-m__cta {
  margin: 14px clamp(18px, 4vw, 32px) 0;
  background: var(--btn-bg); color: #fff !important;
  text-transform: uppercase; letter-spacing: .06em;
  text-align: center; border-radius: var(--radius); border-bottom: 0 !important;
}
.nav-m__cta:hover, .nav-m__cta:focus-visible { background: var(--dark); }
.nav-m__cta + .nav-m__cta { margin-top: 10px; }

@media (max-width: 1140px) {
  .nav { display: none; }
  .burger { display: block; }
  .hdr__cta { margin-left: auto; }
  .hdr__in, .hdr[data-stuck] .hdr__in { min-height: 86px; }
}
/* Phones. The client asked for a quote CTA "up top somewhere to save people
   scrolling the whole page", so it has to survive down to a 360px viewport -
   alongside the brand, a phone link and the burger. At full size that group
   measured 531px inside a 375px viewport: `overflow-x: hidden` on the body hid
   the symptom, so it looked fine and the page was still 156px too wide.
   Everything below is that group being made to genuinely fit. */
@media (max-width: 720px) {
  .hdr__in, .hdr[data-stuck] .hdr__in { gap: 8px; min-height: 74px; }
  .hdr__cta { gap: 8px; }
  .brand { gap: 9px; }
  .brand__mark, .hdr[data-stuck] .brand__mark { width: 32px; height: 32px; }
  .brand__name { font-size: .95rem; line-height: 1.08; max-width: 118px; white-space: normal; }
  .brand__sub { display: none; }
  /* The number itself goes, the black block stays: at 360px the brand, a phone
     button and a burger have to share the row, and the group measured 531px
     inside a 375px viewport before this. `overflow-x:hidden` on the body hid
     that, so it looked perfect and was still 156px too wide. */
  .hdr__phone span { display: none; }
  .hdr__phone { padding: 11px; box-shadow: none; }
  .burger { width: 42px; }
}
@media (max-width: 400px) {
  .wrap { padding-inline: 14px; }
}

/* ---------------------------------------------------------------- hero
   The reference site runs a background slideshow behind a bottom-up black
   gradient. One image plus the same gradient reads identically and costs one
   request. */
/* Photo, then a single black gradient rising from the bottom - the reference's
   own rule is linear-gradient(0deg, rgba(0,0,0,.95) 20%, transparent 100%), so
   the top of the image stays fully bright and all the darkening happens under
   the text. The first build faded the whole photo to 28% at the top, which is
   why its hero read as a grey box rather than a photograph. */
.hero { position: relative; isolation: isolate; background: #111; }
.hero__media { position: absolute; inset: 0; z-index: -2; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; }
.hero::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(0deg, rgba(0,0,0,.95) 20%, rgba(0,0,0,0) 100%);
}
.hero__in {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  text-align: center;                       /* the reference home hero is centred */
  min-height: clamp(460px, 68vh, 700px);
  padding-top: clamp(56px, 9vw, 110px);
  padding-bottom: clamp(40px, 5vw, 62px);
  color: #fff;
  max-width: var(--wrap);
}
.hero__in h1 { color: #fff; max-width: 22ch; }
.hero .eyebrow { color: rgba(255,255,255,.8); }
/* Bold lead sentence, then the paragraph - the reference stacks exactly these
   two. build.mjs emits the first line of .hero__lede in a <strong>. */
.hero__lede {
  font-size: clamp(1.02rem, 1.4vw, 1.12rem);
  max-width: 74ch;
  color: rgba(255,255,255,.94);
  margin-bottom: 1.8em;
}
.hero__lede strong { display: block; margin-bottom: .5em; }
.hero__cta { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }

/* Interior pages keep the reference's OTHER hero treatment - the one on its
   contact page: shorter, and left-aligned rather than centred. */
.hero--sm .hero__in {
  min-height: clamp(300px, 42vh, 430px);
  align-items: flex-start;
  text-align: left;
}
.hero--sm .hero__cta { justify-content: flex-start; }

/* Trust strip under the hero - the reference site's "family owned / warranty"
   promises, pulled up where they are seen before any scrolling. */
.trust { background: var(--dark); color: #fff; }
.trust__in {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 4px clamp(18px, 3vw, 40px);
  padding: 24px 0;
}
.trust__item {
  display: flex; align-items: center; gap: 11px;
  font-size: .93rem; font-weight: 700; color: #fff;
  padding: 7px 0;
}
.trust__item svg { flex: 0 0 auto; color: #fff; }

/* ---------------------------------------------------------------- sections */
.sec { padding-block: var(--sec-y); }
.sec--white { background: #fff; }
.sec--band  { background: var(--band); }
.sec--dark  { background: var(--dark); color: #fff; }
.sec--dark h2, .sec--dark h3 { color: #fff; }
.sec--dark a:not(.btn):not(.card) { color: #fff; }
.sec--dark a:not(.btn):not(.card):hover { color: #fff; }
.sec--tight { padding-block: clamp(32px, 4vw, 56px); }

/* On the reference, a section heading sits on its own line at full width and
   the supporting sentence runs under it - the heading is never squeezed into a
   narrow measure. 900px keeps a 52px heading to two lines at most. */
.sec__head { max-width: 900px; margin-bottom: clamp(28px, 4vw, 46px); }
.sec__head--mid { margin-inline: auto; text-align: center; }
.sec__head p { color: var(--ink-soft); font-size: 1.05rem; max-width: 74ch; }
.sec--dark .sec__head p { color: rgba(255,255,255,.88); }
.sec__head--mid p { margin-inline: auto; }

/* ---------------------------------------------------------------- prose */
.prose h2 { margin-top: 1.7em; }
.prose h2:first-child { margin-top: 0; }
.prose h3 { margin-top: 1.5em; }
.prose ul, .prose ol { margin: 0 0 1.2em; padding-left: 1.25em; }
.prose li { margin-bottom: .45em; }
.prose li::marker { color: var(--ink); }

/* Scope body-link styling away from components. Without :not(.btn) the rule
   below is more specific than .btn and repaints every CTA inside prose. */
.prose a:not(.btn):not(.tlink) {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.prose a:not(.btn):not(.tlink):hover { color: var(--ink); text-decoration-thickness: 2px; }
.sec--dark .prose a:not(.btn):not(.tlink) { color: #fff; }

.prose blockquote {
  margin: 1.6em 0;
  padding: 4px 0 4px 22px;
  border-left: 4px solid var(--ink);
}
.prose blockquote cite {
  display: block; margin-top: .7em; font-style: normal;
  font-weight: 700; font-size: .92rem; color: var(--ink-mute);
}

.split {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 60px);
  align-items: start;
}
.split--flip .split__media { order: -1; }
.split--even { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
/* The reference frames every inline photo in a white border with a drop shadow
   under it, which is what stops the two-column rows looking like a slide deck.
   On a white section the frame is invisible and only the shadow reads - which
   is exactly how it behaves there too. */
.split__media img {
  width: 100%;
  border: 10px solid #fff;
  border-radius: 0;
  box-shadow: 0 8px 26px rgba(0,0,0,.22);
}
.sec--dark .split__media img { border-color: #fff; }
.split__media > * + * { margin-top: 22px; }
@media (max-width: 860px) {
  .split { grid-template-columns: 1fr; }
  .split--flip .split__media { order: 0; }
}

.note {
  font-size: .95rem;
  background: var(--band);
  border-left: 4px solid var(--ink);
  padding: 14px 18px;
  border-radius: var(--radius);
}
.sec--dark .note { background: rgba(255,255,255,.1); color: #fff; border-left-color: #fff; }

/* ---------------------------------------------------------------- feature list
   The reference's "why we stand apart" list: a small SOLID BLACK disc with a
   white tick, a bold lead-in and the explanation running on after it. The disc
   is 30px and sits on the first line of text, not in a 52px column of its own -
   getting that size and alignment right is most of the resemblance. */
.feat { display: grid; gap: clamp(16px, 2vw, 22px); }
.feat__item { display: grid; grid-template-columns: 30px 1fr; gap: 14px; align-items: start; }
.feat__ico {
  width: 30px; height: 30px;
  margin-top: 2px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--ink);
  color: #fff;
}
.feat__ico svg { width: 17px; height: 17px; }
.sec--dark .feat__ico { background: #fff; color: var(--dark); }
.feat__item h3 { font-size: 1.02rem; margin-bottom: .2em; }
.feat__item p { color: var(--ink-soft); margin: 0; font-size: .98rem; }
.sec--dark .feat__item p { color: rgba(255,255,255,.88); }

/* ---------------------------------------------------------------- callout */
.callout {
  background: var(--dark);
  color: #fff;
  border-radius: var(--radius);
  padding: clamp(22px, 3vw, 34px);
}
.callout h3 { color: #fff; margin-bottom: .6em; }
.callout dl { margin: 0; }
.callout dt {
  font-family: var(--font-head); font-weight: 700; font-size: 1.02rem;
  color: #fff; margin-top: 1.1em;
}
.callout dt:first-child { margin-top: 0; }
.callout dd { margin: .2em 0 0; color: rgba(255,255,255,.88); font-size: .97rem; }
.callout__note { display: block; margin-top: 1.4em; font-size: .82rem; color: rgba(255,255,255,.62); }

/* ---------------------------------------------------------------- cards */
/* 🔴 The reference has NO card chrome. Its services grid is a photo, a bold
   heading and a paragraph, sitting directly on the band - no white panel, no
   border, no radius, no shadow, no hover lift. The first build wrapped each one
   in a bordered white card, and that single decision is what made the grid look
   like a different site: the reference's grey band shows THROUGH the grid, and
   a row of white panels covers it up. Do not put the panel back. */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(285px, 1fr));
  gap: clamp(26px, 3vw, 42px);
}
.cards--3 { grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); }
.card {
  display: flex;
  flex-direction: column;
  background: none;
  border: 0;
  color: var(--ink);
  text-decoration: none;
}
.card:hover, .card:focus-visible { text-decoration: none; color: var(--ink); }
.card__img { aspect-ratio: 4 / 3; overflow: hidden; background: var(--line); }
.card__img img { width: 100%; height: 100%; object-fit: cover; transition: transform .4s ease; }
.card:hover .card__img img { transform: scale(1.045); }
.card__body { padding: 20px 0 0; display: flex; flex-direction: column; flex: 1 1 auto; }
.card__body h3 { margin-bottom: .5em; }
.card:hover .card__body h3 { text-decoration: underline; text-underline-offset: 3px; }
.card__body p { color: var(--ink-soft); font-size: .98rem; margin-bottom: 1.1em; }
.card__more {
  margin-top: auto;
  font-weight: 700; font-size: .86rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink);
}
.sec--dark .card, .sec--dark .card:hover { color: #fff; }
.sec--dark .card__body p { color: rgba(255,255,255,.88); }
.sec--dark .card__more { color: #fff; }
/* Not every card is a link. A hover cue on something with no destination reads
   as a broken button, so the static variant drops it. */
.card--static { cursor: default; }
.card--static:hover .card__img img { transform: none; }
.card--static:hover .card__body h3 { text-decoration: none; }

/* ---------------------------------------------------------------- reviews */
/* Yellow stars over a centred heading - the one place the reference allows any
   colour on the page, and it comes from the star glyphs themselves. */
.reviews { text-align: center; }
.reviews__stars { margin: 0 auto 16px; width: 132px; }
.reviews h2 { max-width: 34ch; margin-inline: auto; font-size: clamp(1.5rem, 2.6vw, 2.05rem); }
.reviews__note {
  max-width: 62ch; margin: 0 auto 24px; color: var(--ink-soft);
}
/* Collapses to nothing until a review widget is actually wired in - an empty
   60px gap between the copy and the buttons reads as a broken embed. */
.reviews__slot:empty { display: none; }
.reviews__slot { margin: 0 0 22px; }
.reviews__cta { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }

/* ---------------------------------------------------------------- process */
.steps { counter-reset: step; display: grid; gap: clamp(18px, 2.4vw, 26px); }
.step {
  counter-increment: step;
  display: grid; grid-template-columns: 44px 1fr; gap: 16px; align-items: start;
}
.step::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-head); font-weight: 700; font-size: 1rem;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--ink); color: #fff;
}
.sec--dark .step::before { background: #fff; color: var(--dark); }
.step h3 { margin-bottom: .3em; }
.step p { margin: 0; color: var(--ink-soft); font-size: .98rem; }
.sec--dark .step p { color: rgba(255,255,255,.86); }

/* ---------------------------------------------------------------- gallery */
.gal {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: clamp(14px, 2vw, 26px);   /* the reference gallery is generously spaced */
}
/* The home page shows exactly six. At the full-width auto-fill above that lands
   as five plus a lone orphan; wider columns give two clean rows of three. */
.gal--six { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.gal__btn {
  padding: 0; border: 0; background: var(--band);
  aspect-ratio: 4 / 3; overflow: hidden; cursor: zoom-in;
  border-radius: var(--radius);
}
.gal__btn img { width: 100%; height: 100%; object-fit: cover; transition: transform .35s ease; }
.gal__btn:hover img, .gal__btn:focus-visible img { transform: scale(1.06); }

.lb {
  position: fixed; inset: 0; z-index: 300;
  display: none;
  background: rgba(10,10,10,.94);
  padding: clamp(12px, 3vw, 40px);
}
.lb[data-open] { display: grid; grid-template-rows: 1fr auto; place-items: center; }
.lb__img {
  max-width: min(1200px, 100%); max-height: 78vh;
  width: auto; object-fit: contain; border-radius: var(--radius);
}
.lb__cap { color: #fff; text-align: center; font-size: .92rem; padding-top: 14px; max-width: 70ch; }
.lb__btn {
  position: absolute;
  background: rgba(255,255,255,.14);
  border: 1px solid rgba(255,255,255,.32);
  color: #fff; width: 48px; height: 48px;
  border-radius: 50%; cursor: pointer;
  display: grid; place-items: center;
  font-size: 1.3rem; line-height: 1;
}
.lb__btn:hover { background: rgba(255,255,255,.3); }
.lb__close { top: clamp(10px, 2vw, 24px); right: clamp(10px, 2vw, 24px); }
.lb__prev  { left: clamp(6px, 2vw, 24px); top: 50%; transform: translateY(-50%); }
.lb__next  { right: clamp(6px, 2vw, 24px); top: 50%; transform: translateY(-50%); }
body[data-lb] { overflow: hidden; }
body[data-lb] .hdr { display: none; }

/* ---------------------------------------------------------------- FAQ band
   🔴 Inverted from the first build to match the reference exactly. There the
   photo stays BRIGHT and a near-white panel is laid over the middle of it,
   holding a centred black heading and a stack of dark accordion bars. The
   first build darkened the whole photo to 85% black and set the questions in
   white on hairline rules - the same content, and nothing about it recognisable
   as the same design. */
.faq-band {
  position: relative;
  isolation: isolate;
  background: var(--dark);
  color: var(--ink);
  padding-block: clamp(50px, 7vw, 100px);
}
.faq-band__bg {
  position: absolute; inset: 0; z-index: -2;
  background-image: url('/assets/img/bg-faq-rural-fencing.jpg');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
/* background-attachment: fixed is skipped on touch devices - iOS renders it at
   the wrong scale and it costs a repaint on every scroll frame. */
@media (hover: hover) and (min-width: 900px) {
  .faq-band__bg { background-attachment: fixed; }
}
/* A light scrim only - just enough to hold the panel off a busy photograph. */
.faq-band::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: rgba(0,0,0,.28);
}

/* The panel. Near-white and translucent, so the photograph still reads behind
   it, and centred in the band. */
.faq {
  max-width: 960px;
  margin-inline: auto;
  background: rgba(255,255,255,.93);
  padding: clamp(28px, 4.5vw, 56px) clamp(20px, 3.5vw, 44px);
  text-align: center;
}
.faq-band h2, .faq-band h3 { color: var(--ink); }
.faq > h2 { font-size: clamp(1.55rem, 3vw, 2.3rem); margin-bottom: 1em; }
.faq > .eyebrow { color: var(--ink-mute); }

/* Each question is a solid dark BAR, not a hairline rule. Closed bars are
   #333334, the open one goes to pure black - that step is how the reference
   shows which is expanded, and it is only visible if the closed state is not
   already black. */
.faq details { margin-bottom: 12px; text-align: left; }
.faq summary {
  cursor: pointer;
  list-style: none;
  display: flex; justify-content: space-between; align-items: center; gap: 18px;
  padding: 15px 22px;
  background: var(--dark);
  font-family: var(--font-body); font-weight: 400;
  font-size: clamp(1rem, 1.4vw, 1.08rem);
  color: #fff;
  transition: background .16s ease;
}
.faq summary:hover { background: var(--darker); }
.faq details[open] summary { background: var(--sage-dk); }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+';
  flex: 0 0 auto;
  font-size: 1.4rem; line-height: 1; color: #fff;
}
.faq details[open] summary::after { content: '\2212'; }   /* a true minus sign */
.faq details p, .faq details ul { color: var(--ink); font-size: .99rem; }
.faq details > *:not(summary) { margin: 1em 0 0; padding-inline: 22px; }
.faq details > *:last-child { margin-bottom: 22px; }

/* ---------------------------------------------------------------- areas */
.areas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
}
.area {
  background: #fff;
  border: 0;
  border-left: 3px solid var(--ink);
  border-radius: var(--radius);
  padding: 16px 18px;
}
.sec--dark .area { background: rgba(255,255,255,.08); border-left-color: #fff; color: #fff; }
.area h3 { font-size: 1.05rem; margin-bottom: .35em; }
.area p { font-size: .93rem; color: var(--ink-soft); margin: 0; }

/* ---------------------------------------------------------------- enquiry
   The reference's pre-footer block: a WHITE section, the brand and a big
   heading down the left, and the form in a solid #333334 panel on the right
   with plain white fields inside it. The first build had it the other way
   round - a light grey section with a white card - which is the same
   arrangement wearing none of the same clothes. */
.enq { background: #fff; padding-block: var(--sec-y); }
.enq__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .95fr);
  gap: clamp(28px, 4vw, 64px);
  align-items: start;
}
@media (max-width: 860px) { .enq__grid { grid-template-columns: 1fr; } }
.enq__copy p { color: var(--ink-soft); }
.enq__copy h2 { font-size: clamp(1.7rem, 3.2vw, 2.5rem); }
.enq__big {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(1.4rem, 3vw, 2rem);
  color: var(--ink) !important;
  text-decoration: none !important;
  margin-bottom: .5em;
}
.enq__big:hover { text-decoration: underline !important; }
.enq__facts { list-style: none; margin: 1.2em 0; padding: 0; }
.enq__facts li {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 10px 0; border-bottom: 1px solid var(--line);
  font-size: .97rem;
}
.enq__facts svg { flex: 0 0 auto; margin-top: 4px; color: var(--ink); }
.enq__note { font-size: .87rem; color: var(--ink-mute); }

.form {
  background: var(--dark);
  border: 0;
  border-radius: var(--radius);
  padding: clamp(22px, 3vw, 34px);
  box-shadow: none;
  color: #fff;
}
.form__row { margin-bottom: 14px; }
.form label {
  display: block; font-weight: 400; font-size: .9rem;
  margin-bottom: 6px; color: #fff;
}
/* 🔴 Every colour is stated outright. A field that inherits its colour from the
   panel renders white-on-white and the form silently disappears while the panel
   around it still looks perfect - the failure that cost an afternoon on
   mortgage-iq. -webkit-text-fill-color goes alongside `color` because WebKit
   honours it in preference. */
.form input, .form select, .form textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 12px 14px;
  border: 1px solid #fff;
  border-radius: var(--radius);
  background: #fff;
  color: var(--ink);
  -webkit-text-fill-color: #3f3f3d;
}
.form ::placeholder { color: #6a6a6a; opacity: 1; }
.form textarea { resize: vertical; min-height: 118px; }
.form input:focus, .form select:focus, .form textarea:focus {
  outline: none; border-color: #fff;
  box-shadow: 0 0 0 3px rgba(255,255,255,.45);
}
/* White submit on the dark panel, as the reference's SEND. */
.form .btn {
  width: 100%; margin-top: 6px;
  background: var(--sage); border-color: var(--sage); color: var(--ink);
}
.form .btn:hover, .form .btn:focus-visible {
  background: #fff; border-color: #fff; color: var(--ink);
}
.err { display: block; color: #ffb4b0; font-size: .85rem; margin-top: 5px; }
.form__msg { margin: 12px 0 0; font-size: .93rem; min-height: 1.2em; color: #fff; }
.form__msg.err { color: #ffb4b0; }
.form__legal { font-size: .8rem; color: rgba(255,255,255,.72); margin-top: 14px; }

/* Honeypot. Off-canvas, not display:none and not type=hidden - capable bots
   skip both. The server check is the real one; this only catches the crude. */
.hp {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px; overflow: hidden;
}

/* ---------------------------------------------------------------- footer
   #333334, three columns - contact details as an icon list, a link column
   whose rows are separated by hairline rules, and a paragraph about the
   business - then a full-width service-areas line, then a PURE BLACK strip
   holding one line of small centred credit text. The black strip is what ends
   the reference page, and leaving it off (as the first build did) is
   surprisingly noticeable. */
.ftr { background: var(--dark); color: rgba(255,255,255,.86); padding-top: clamp(40px, 5vw, 66px); }
.ftr__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(255px, 1fr));
  gap: clamp(26px, 3.5vw, 54px);
  padding-bottom: clamp(24px, 3vw, 34px);
}
.ftr h3 {
  color: #fff; font-size: 1.28rem; letter-spacing: 0;
  text-transform: none; margin-bottom: .8em;
}
.ftr p { font-size: .96rem; color: rgba(255,255,255,.86); }
.ftr a { display: block; padding: 5px 0; font-size: .96rem; color: rgba(255,255,255,.9); }
.ftr a:hover, .ftr a:focus-visible { color: #fff; text-decoration: underline; }
.ftr .brand { color: #fff; margin-bottom: 16px; }
.ftr .brand:hover { color: #fff; }
.ftr .brand__sub { color: rgba(255,255,255,.7); }

/* The link column: a rule under each row, none under the last. */
.ftr__links a {
  padding: 11px 4px 11px 10px;
  border-bottom: 1px solid rgba(255,255,255,.28);
}
.ftr__links a:last-child { border-bottom: 0; }

/* The contact column: a glyph, then the value, aligned on the first line. */
.ftr__contact { list-style: none; margin: 0 0 14px; padding: 0; }
.ftr__contact li { display: flex; gap: 13px; align-items: flex-start; padding: 7px 0; font-size: .96rem; }
.ftr__contact svg { flex: 0 0 auto; margin-top: 4px; color: #fff; }
.ftr__contact a { display: inline; padding: 0; }
.ftr__social { display: flex; gap: 12px; margin-top: 10px; }
.ftr__social a { display: inline-flex; padding: 0; color: #fff; }
.ftr__social a:hover { opacity: .75; text-decoration: none; }

.ftr__areas-row { padding-bottom: clamp(28px, 4vw, 44px); }
.ftr__areas-row h3 { margin-bottom: .55em; }
.ftr__areas { font-size: .96rem; color: rgba(255,255,255,.86); }
/* .ftr a is display:block for the link column; this one runs inside a sentence. */
.ftr__areas a { display: inline; padding: 0; text-decoration: underline; }

/* The black strip. Full-bleed, so it needs its own background rather than
   living inside .ftr's padding. */
.ftr__btm-wrap { background: var(--darker); }
.ftr__btm {
  display: flex; flex-wrap: wrap; gap: 6px 22px;
  justify-content: center; align-items: center; text-align: center;
  padding-block: 16px;
  font-size: .82rem;
  color: rgba(255,255,255,.8);
}
/* Fleet standard: the WHOLE phrase is the link, underlined on hover only, so
   it reads as a credit rather than competing with the footer nav. */
.ftr__credit { display: inline !important; padding: 0 !important; color: rgba(255,255,255,.8) !important; }
.ftr__credit:hover, .ftr__credit:focus-visible { color: #fff !important; text-decoration: underline; }

/* ---------------------------------------------------------------- float bar
   Fleet component: expandable icon stack, lower right. Every link and colour
   comes from /dash, and a blank field renders no icon at all - the bar is only
   ever as big as what the client filled in. */
.floatbar {
  position: fixed;
  right: clamp(12px, 2vw, 22px);
  bottom: clamp(12px, 2vw, 22px);
  z-index: 95;
  display: flex; flex-direction: column-reverse; align-items: center; gap: 9px;
  /* Defaults only - /dash overrides all four at runtime. Charcoal button with a
     sage hover, so the bar reads as this brand rather than as a generic black
     widget bolted onto the corner. White on charcoal is 10.55:1; charcoal on
     sage is 4.60:1, so the hover state stays legible in both directions. */
  --fb-bg: #3f3f3d;
  --fb-icon: #ffffff;
  --fb-hover-bg: #a5b176;
  --fb-hover-icon: #3f3f3d;
}
.floatbar__btn {
  width: 50px; height: 50px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--fb-bg);
  color: var(--fb-icon);
  border: 0; cursor: pointer;
  box-shadow: 0 3px 12px rgba(0,0,0,.28);
  transition: background .16s ease, color .16s ease, transform .16s ease;
  text-decoration: none;
}
.floatbar__btn:hover, .floatbar__btn:focus-visible {
  background: var(--fb-hover-bg);
  color: var(--fb-hover-icon);
  transform: scale(1.08);
  text-decoration: none;
}
.floatbar__toggle { order: 1; }
.floatbar__list { display: flex; flex-direction: column-reverse; gap: 9px; }
/* Collapse is scoped to .cnc-js so a visitor with no JS gets the full stack
   rather than an empty bar. */
.cnc-js .floatbar:not([data-open]) .floatbar__list { display: none; }
/* Restated AFTER the collapse rule: an equal-specificity `transform: none`
   later in the file silently killed the hover scale on the reference build. */
.floatbar__list .floatbar__btn:hover,
.floatbar__list .floatbar__btn:focus-visible { transform: scale(1.08); }

.fb-pop {
  position: fixed; inset: 0; z-index: 300;
  display: none; place-items: center;
  background: rgba(10,10,10,.7);
  padding: 20px;
}
.fb-pop[data-open] { display: grid; }
.fb-pop__card {
  position: relative;
  background: #fff; border-radius: var(--radius);
  padding: 34px 40px; text-align: center; max-width: 380px;
}
.fb-pop__card p { color: var(--ink-soft); font-size: .95rem; }
.fb-pop__num {
  display: block; font-family: var(--font-head); font-weight: 700;
  font-size: clamp(1.5rem, 5vw, 2.1rem); color: var(--ink); margin-bottom: .3em;
  text-decoration: none;
}
.fb-pop__close {
  position: absolute; top: 8px; right: 8px;
  width: 36px; height: 36px; border: 0; background: transparent;
  font-size: 1.4rem; line-height: 1; cursor: pointer; color: var(--ink-mute);
}

/* ---------------------------------------------------------------- reveal
   threshold: 0 with rootMargin only. A ratio threshold never fires for an
   element taller than about 16x the viewport, and a service page's copy column
   is routinely 4,000px+ - so the whole body would sit at opacity 0 until the
   visitor happened to scroll. Scoped to .cnc-js so crawlers and no-JS visitors
   always see everything. */
.cnc-js [data-reveal] { opacity: 0; transform: translateY(18px); }
.cnc-js [data-reveal].is-in {
  opacity: 1; transform: none;
  transition: opacity .55s ease, transform .55s ease;
}
.cnc-js [data-reveal][data-delay="1"].is-in { transition-delay: .12s; }
.cnc-js [data-reveal][data-delay="2"].is-in { transition-delay: .24s; }
@media (prefers-reduced-motion: reduce) {
  .cnc-js [data-reveal] { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------- print */
@media print {
  .hdr, .floatbar, .enq, .lb, .fb-pop { display: none !important; }
  body { font-size: 12pt; }
  .hero::after { display: none; }
}

/* ===========================================================================
   CUSTOM FENCE CONSULTING - the components this site adds
   ---------------------------------------------------------------------------
   Everything above is inherited from the All Fencing Solutions build. This
   block is what an advisory site needs and a contractor site does not: a real
   logo lockup instead of live text, a page header for pages that have no hero
   photo, credential display, a twelve-item service architecture, an industries
   directory and long-form service sections.
   =========================================================================== */

/* ---------------------------------------------------------------- brand
   Unlike the reference, this client DOES have artwork - so the header shows
   the real lockup rather than typeset text. Height-driven so the wordmark
   keeps its proportions whatever the file's pixel width, and it shrinks with
   the sticky header. */
.brand__logo {
  width: auto;
  height: 56px;
  transition: height .22s ease;
}
.hdr[data-stuck] .brand__logo { height: 44px; }
@media (prefers-reduced-motion: reduce) { .brand__logo { transition: none; } }
/* The wide lockup is ~5:1, so height is what governs how much of the row it eats.
   Below the desktop breakpoint the burger and the phone block need the space. */
@media (max-width: 1140px) { .brand__logo, .hdr[data-stuck] .brand__logo { height: 42px; } }
@media (max-width: 460px)  { .brand__logo, .hdr[data-stuck] .brand__logo { height: 34px; } }
@media (max-width: 360px)  { .brand__logo, .hdr[data-stuck] .brand__logo { height: 29px; } }

/* ---------------------------------------------------------------- nav
   🔴 TWELVE services will not fit in the inherited single-column dropdown -
   thirteen rows at 38px is ~500px, taller than the visible area under the
   header on a laptop, so the last items sit off screen with no way to reach
   them. Two columns, and an "All services" row across the top of both. */
/* Multi-column rather than a two-column GRID. With a grid, every row is as tall
   as its tallest cell, so the one item that wraps to two lines ("Councils &
   large organisations") opens a blank gap beside itself in the other column and
   the menu reads as though an entry is missing. Columns flow instead. */
.nav__panel--wide {
  min-width: 520px;
  padding: 10px 0 12px;
  columns: 2;
  column-gap: 6px;
}
.nav__panel-all {
  column-span: all;
  font-weight: 700;
  border-bottom: 1px solid var(--line) !important;
  margin-bottom: 6px;
  padding-bottom: 12px !important;
}
.nav__panel--wide a { white-space: normal; line-height: 1.3; break-inside: avoid; }
/* The panel is wider than the button it hangs from, so at narrower desktop
   widths a centred panel runs off the right edge of the viewport. Pin it to
   the left of the trigger instead once there is not room to centre it. */
@media (max-width: 1240px) {
  .nav__panel--wide { left: 0; transform: none; }
}

/* Mobile menu: the twelve services are indented under "All services" so the
   list reads as a hierarchy rather than as twenty flat rows. */
.nav-m__sub {
  padding-left: 22px !important;
  font-size: .92rem !important;
  opacity: .84;
}

/* ---------------------------------------------------------------- hero
   The colour underneath is what shows for the instant before the photo paints,
   so it is the brand charcoal rather than a generic near-black. */
.hero { background: var(--dark); }

/* 🔴 The inherited scrim rises from the BOTTOM ONLY - fine over the reference
   site's dark photo, wrong over a bright one. The hero here is a sunlit
   roadside with a pale sky behind it, and white on that measured under 3:1. So
   the bottom-up gradient is kept for the CTA, and a second, even wash is laid
   over the whole frame to carry the heading. Both together read as a darker
   photograph rather than as a grey panel. */
.hero::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(46,46,44,.62) 0%, rgba(46,46,44,.34) 45%, rgba(46,46,44,.52) 100%);
}
.hero::after {
  background: linear-gradient(0deg, rgba(30,30,28,.92) 12%, rgba(30,30,28,0) 78%);
}
.hero__lead {
  color: rgba(255,255,255,.93);
  font-size: clamp(1.02rem, 1.5vw, 1.16rem);
  line-height: 1.6;
  max-width: 62ch;
  margin: 0 auto 26px;
}

/* An eyebrow on a dark ground. The brand sage measures 4.60:1 on the flat
   charcoal band, so unlike on white it can carry small text there. */
.eyebrow--light { color: var(--sage); }
.sec__head--light p { color: rgba(255,255,255,.88); }

/* 🔴 ...but NOT over the hero PHOTOGRAPH. Sampled off the live deployment, the
   background behind the hero eyebrow reached #727466 at its brightest, which
   puts sage at 2.08:1 there - nowhere near the 4.5:1 small letter-spaced
   uppercase text needs. White measures 4.77:1 against that same sample, so the
   hero eyebrow is white and only the flat-charcoal .phead keeps the sage.
   The lesson: "sage passes on charcoal" is true of the BAND, not of a photo
   with a charcoal wash over it. Measure the pixels, not the token. */
.hero .eyebrow--light { color: rgba(255,255,255,.92); }

/* ---------------------------------------------------------------- page head
   Pages without a hero photograph still need a top. A sage rule under the
   charcoal keeps the brand present without inventing another photograph. */
.phead {
  background: var(--dark);
  color: #fff;
  padding-block: clamp(34px, 5vw, 62px);
  border-bottom: 5px solid var(--sage);
}
.phead--tall { padding-block: clamp(56px, 9vw, 110px); text-align: center; }
.phead--tall .hero__cta { justify-content: center; margin-top: 26px; flex-wrap: wrap; }
.phead h1 { color: #fff; margin-bottom: .35em; }
.phead__lead {
  color: rgba(255,255,255,.9);
  font-size: clamp(1.02rem, 1.5vw, 1.16rem);
  line-height: 1.6;
  max-width: 68ch;
  margin: 0;
}
.phead--tall .phead__lead { margin-inline: auto; }
.phead__lead a { color: #fff; }

.crumbs { font-size: .84rem; color: rgba(255,255,255,.72); margin-bottom: 14px; }
.crumbs a { color: rgba(255,255,255,.92); }
.crumbs > span { margin-inline: 5px; }

/* ---------------------------------------------------------------- cards
   A kicker above the card heading, because the headings on this site are
   sentences rather than labels, and someone scanning still needs the label. */
.card__kicker {
  display: block;
  font-family: var(--font-ui);
  font-size: .74rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--sage-dk);
  margin-bottom: 8px;
}
/* The "what usually prompts someone to ring" cards carry no photograph, so
   they need their own top rule to separate them from the band. */
.card--static { border-top: 3px solid var(--sage); padding-top: 20px; }
.card--static .card__body { padding-top: 0; }
.card--static .card__more { color: var(--sage-dk); }
.card--static .card__more:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ---------------------------------------------------------------- services grid
   🔴 TWELVE services cannot be a photo card grid. At 4:3 with a paragraph each
   that is roughly 4,000px of scrolling on desktop and far more on a phone, and
   the visitor stops reading at about number five - so the two services Nick
   most wants seen (disputes at 08, asset management at 09) fall below the point
   at which anybody is still looking. A numbered link list shows all twelve in
   one screen and reads like a consultancy's capability list, which is what it
   is. The photographs live on the detail pages, where there is one each. */
.svcgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
  gap: 2px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.svcgrid__item {
  display: grid;
  grid-template-columns: 40px 1fr;
  gap: 14px;
  align-items: start;
  background: #fff;
  padding: 20px 22px;
  color: var(--ink);
  text-decoration: none;
  transition: background .16s ease;
}
@media (prefers-reduced-motion: reduce) { .svcgrid__item { transition: none; } }
.svcgrid__item:hover, .svcgrid__item:focus-visible {
  background: var(--band-2);
  color: var(--ink);
  text-decoration: none;
}
.svcgrid__no {
  font-family: var(--font-head);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--sage-dk);
  line-height: 1.35;
}
.svcgrid__body { display: block; }
.svcgrid__name {
  display: block;
  font-family: var(--font-head);
  font-size: 1.06rem;
  font-weight: 700;
  line-height: 1.3;
  margin-bottom: 5px;
}
.svcgrid__item:hover .svcgrid__name { text-decoration: underline; text-underline-offset: 3px; }
.svcgrid__lead {
  display: block;
  font-size: .93rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.svcgrid__all { margin: clamp(22px, 3vw, 32px) 0 0; text-align: center; }

/* ---------------------------------------------------------------- industries
   Nick asked for the eleven sectors to shape the copy "so we get it right", so
   they are a real navigational element, not a badge row. */
.indgrid {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
}
.indgrid__item {
  display: inline-block;
  padding: 9px 17px;
  border: 1px solid var(--line);
  border-radius: 100px;
  background: #fff;
  font-size: .94rem;
  color: var(--ink);
  text-decoration: none;
  transition: background .16s ease, border-color .16s ease;
}
@media (prefers-reduced-motion: reduce) { .indgrid__item { transition: none; } }
.indgrid__item:hover, .indgrid__item:focus-visible {
  background: var(--dark); border-color: var(--dark); color: #fff; text-decoration: none;
}

.inds {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(18px, 2.4vw, 26px);
}
.ind {
  background: #fff;
  border-top: 4px solid var(--sage);
  border-radius: var(--radius);
  padding: 24px 22px;
  scroll-margin-top: 96px;
}
.ind h3 { margin-bottom: .45em; }
.ind p { color: var(--ink-soft); font-size: .96rem; }
.ind__links {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: .86rem;
  color: var(--ink-mute);
}
.ind__links a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }

/* ---------------------------------------------------------------- split extras */
.split__cap {
  font-size: .88rem;
  line-height: 1.5;
  color: var(--ink-mute);
  border-left: 3px solid var(--sage);
  padding-left: 12px;
  margin: 0;
}
.sec--dark .split__cap { color: rgba(255,255,255,.78); }

/* The closing line of a passage. Set larger and in the display serif so a
   section ends on its argument rather than trailing off. */
.split__kicker {
  font-family: var(--font-head);
  font-size: 1.14rem;
  line-height: 1.45;
  color: var(--ink);
  border-top: 1px solid var(--line);
  padding-top: 18px;
  margin-top: 24px;
}
.sec--dark .split__kicker { color: #fff; border-top-color: rgba(255,255,255,.28); }

/* A caveat, deliberately distinct from the argument around it. */
.split__note, .creds__note {
  background: var(--band-2);
  border-left: 4px solid var(--sage-dk);
  padding: 15px 18px;
  font-size: .95rem;
  border-radius: var(--radius);
}
.sec--band .split__note, .sec--band .creds__note { background: #fff; }
.sec--dark .split__note { background: rgba(255,255,255,.1); color: #fff; }

/* ---------------------------------------------------------------- ticks */
.ticks { list-style: none; margin: 0 0 1.3em; padding: 0; }
.ticks li {
  position: relative;
  padding-left: 30px;
  margin-bottom: .6em;
  line-height: 1.55;
}
.ticks li::before {
  content: "";
  position: absolute; left: 0; top: .42em;
  width: 15px; height: 15px;
  background: var(--sage-dk);
  -webkit-mask: var(--ico-tick) center / contain no-repeat;
          mask: var(--ico-tick) center / contain no-repeat;
}
.sec--dark .ticks li::before { background: var(--sage); }
/* The hub lists Nick's own bullet points, and several services carry nine of
   them. One column of nine short phrases is a very tall, very thin block. */
.ticks--two { columns: 2; column-gap: clamp(20px, 3vw, 44px); }
.ticks--two li { break-inside: avoid; }
@media (max-width: 680px) { .ticks--two { columns: 1; } }

/* ---------------------------------------------------------------- services hub
   Each of the twelve as a numbered block carrying Nick's own bullet list. */
.hub { scroll-margin-top: 96px; padding-block: clamp(26px, 3.4vw, 46px); }
.hub__in { display: block; }
.hub__head { display: grid; grid-template-columns: auto 1fr; gap: 16px; align-items: baseline; }
.hub__no {
  font-family: var(--font-head);
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  font-weight: 700;
  color: var(--sage);
  line-height: 1;
}
.hub__head h2 { margin-bottom: .25em; }
.hub__lead { color: var(--ink-soft); margin-bottom: 0; max-width: 74ch; }
.hub__body { margin-top: 20px; padding-left: calc(clamp(1.6rem, 3vw, 2.2rem) + 16px); }
.hub__body .ticks { margin-bottom: 1em; }
@media (max-width: 680px) { .hub__body { padding-left: 0; } }

/* ---------------------------------------------------------------- service page
   The scroll-margin makes in-page anchors land below the sticky header. */
.svc { scroll-margin-top: 96px; }

/* The inherited .split aligns both columns to the TOP, which is right when the
   two are a similar height. On a service page the copy column runs to three
   paragraphs and the photograph is a third of that, so a top-aligned image
   leaves 200px of void beside the text and the row reads as unfinished. Centring
   the media against the copy fixes it without touching the shared component.
   Only on the service pages: on the home and about splits the columns are
   already close in height, and centring there would misalign the eyebrow. */
.split--svc .split__media { align-self: center; }

/* The "what this covers" list on a service detail page. Two columns, because
   the longest of them (farm and lifestyle) carries nine items. */
.feat--two {
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
  column-gap: clamp(24px, 3.5vw, 52px);
}
.feat__ico { background: var(--sage-dk); }

/* ---------------------------------------------------------------- credentials
   🔴 On a GENUINELY WHITE section, never the warm band - white logo artwork
   shows its edge against off-white. Full colour, never greyscaled: this is a
   third-party certification mark and being recognised is its entire job.

   This block is also the independence disclosure, and it is the ONLY place on
   the site that names the contracting company. See build/build.mjs. */
.creds {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px);
  align-items: center;
}
.creds__marks {
  display: grid;
  gap: 20px;
  justify-items: center;
  background: var(--band);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(22px, 3vw, 32px);
}
.creds__marks img { max-width: 300px; width: 100%; }
.creds__cred {
  font-size: .92rem;
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 0;
  text-align: left;
}
.creds__note { margin-bottom: 0; }
@media (max-width: 860px) { .creds { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------- steps
   🔴 The inherited .step is a HORIZONTAL row - `grid-template-columns: 44px 1fr`
   with the counter disc, the h3 and the p as three grid items. That places the
   disc and the heading on row one and drops the PARAGRAPH INTO THE 44px COLUMN
   on row two, so every step rendered one word per line in a 44px ribbon. It is
   only wrong once the steps are laid out three-across, which is why it does not
   show on the site this was forked from. Restated as a block here rather than
   patched, so the columns cannot come back.
   The counter disc is charcoal by default; on the dark band that disappears, so
   it inverts to sage with charcoal digits (4.60:1). */
.steps { grid-template-columns: repeat(auto-fit, minmax(275px, 1fr)); }
.step { display: block; }
.step::before { margin-bottom: 16px; }
.sec--dark .step::before { background: var(--sage); color: var(--dark); }
.step h3 { margin-bottom: .4em; }
.step p { font-size: .97rem; margin: 0; color: var(--ink-soft); }
.sec--dark .step p { color: rgba(255,255,255,.86); }

/* ---------------------------------------------------------------- tiles */
.grid3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(285px, 1fr));
  gap: clamp(18px, 2.4vw, 28px);
}
.tile {
  background: rgba(255,255,255,.07);
  border: 1px solid rgba(255,255,255,.17);
  border-radius: var(--radius);
  padding: 24px 22px;
}
.tile h3 { color: #fff; margin-bottom: .45em; }
.tile p { color: rgba(255,255,255,.86); font-size: .96rem; margin: 0; }
.sec--white .tile, .sec--band .tile { background: #fff; border-color: var(--line); }
.sec--white .tile h3, .sec--band .tile h3 { color: var(--ink); }
.sec--white .tile p, .sec--band .tile p { color: var(--ink-soft); }

/* ---------------------------------------------------------------- related services
   The .group card was built for the "three companies in the group" block, which
   has been REMOVED - Nick's feedback was that the site leaned too heavily on the
   contracting company. The card itself is good, so it now carries the three
   related services at the foot of each detail page. */
.group {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(285px, 1fr));
  gap: clamp(18px, 2.4vw, 26px);
}
.group__card {
  display: flex; flex-direction: column;
  background: #fff;
  border: 1px solid var(--line);
  border-top: 4px solid var(--sage);
  border-radius: var(--radius);
  padding: 26px 24px;
  color: var(--ink);
  text-decoration: none;
  transition: box-shadow .18s ease, transform .18s ease;
}
@media (prefers-reduced-motion: reduce) { .group__card { transition: none; } }
a.group__card:hover, a.group__card:focus-visible {
  text-decoration: none; color: var(--ink);
  box-shadow: var(--shadow); transform: translateY(-3px);
}
a.group__card:hover h3 { text-decoration: underline; text-underline-offset: 3px; }
.group__card h3 { margin-bottom: .5em; }
.group__card p { color: var(--ink-soft); font-size: .97rem; flex: 1 1 auto; }

/* ---------------------------------------------------------------- contact */
.contact {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(235px, 1fr));
  gap: clamp(16px, 2.2vw, 24px);
}
.contact__card {
  display: block;
  background: var(--band);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px 24px;
  color: var(--ink);
  text-decoration: none;
  transition: box-shadow .18s ease, transform .18s ease;
}
@media (prefers-reduced-motion: reduce) { .contact__card { transition: none; } }
a.contact__card:hover, a.contact__card:focus-visible {
  text-decoration: none; color: var(--ink);
  box-shadow: var(--shadow); transform: translateY(-3px);
}
.contact__card svg { color: var(--sage-dk); margin-bottom: 12px; }
.contact__card h2, .contact__card h3 { margin-bottom: .3em; }
.contact__card p { color: var(--ink-soft); font-size: .96rem; margin: 0; }
.contact__card--static { cursor: default; }
/* The phone card is the primary action on the page, so it is charcoal and it
   spans two columns wherever there is room for two. */
.contact__card--lead {
  background: var(--dark);
  border-color: var(--dark);
  color: #fff;
  grid-column: span 2;
}
.contact__card--lead h2 { color: #fff; font-size: clamp(1.7rem, 3.4vw, 2.5rem); }
.contact__card--lead p { color: rgba(255,255,255,.86); }
.contact__card--lead svg { color: var(--sage); }
a.contact__card--lead:hover, a.contact__card--lead:focus-visible { color: #fff; }
@media (max-width: 620px) { .contact__card--lead { grid-column: span 1; } }

/* ---------------------------------------------------------------- banner
   ONE credential, given a band of its own on the home page. Nick asked for it
   on 7 August 2026 "just to add some additional reassurance", and it is the
   first hard biographical fact anybody has supplied for this site.

   It sits directly beneath the dark .trust strip, so it uses --band-2 rather
   than --band: against the charcoal strip above and the white section below,
   the lighter tint reads as a continuation of the white and the banner stops
   looking like a deliberate element. Charcoal on --band-2 measures 8.72:1.

   No .card, no shadow, no reveal. It is a statement, and it is placed where it
   has to be legible in the first screen of a phone - so it must never depend on
   IntersectionObserver having fired. */
.banner {
  background: var(--band-2);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
/* 🔴 padding-block ONLY, never the `padding: X 0` shorthand. This element is a
   .wrap as well, and .wrap's whole job is the horizontal gutter - the shorthand
   resets left and right to zero and the banner runs edge to edge on a phone.
   Invisible on desktop, where .wrap is centred by max-width and auto margins
   instead, so the gutter is not what is holding the text off the edge. */
.banner__in {
  display: flex;
  align-items: center;
  gap: clamp(15px, 2.4vw, 26px);
  padding-top: clamp(20px, 3vw, 30px);
  padding-bottom: clamp(20px, 3vw, 30px);
}
/* The disc is decoration, so it is the one place sage is safe at full strength -
   it carries no text. */
.banner__mark {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: var(--sage);
  color: var(--dark);
}
/* Capped, or the note runs to a ~150-character measure on a wide monitor and
   nobody finishes the line. The lead is short enough to sit on one line either
   way, so the cap costs the headline statement nothing. */
.banner__copy { min-width: 0; max-width: 88ch; }
.banner__lead {
  margin: 0;
  font-size: clamp(1.02rem, 1.5vw, 1.2rem);
  line-height: 1.45;
  color: var(--ink);
}
.banner__lead strong { color: var(--accent-dk); }
/* A year range that wraps reads as two numbers - "2022-" then "2025." landed on
   the second line at 1440px. Keep it whole wherever it appears. */
.nobr { white-space: nowrap; }
.banner__note {
  margin: 6px 0 0;
  font-size: .92rem;
  line-height: 1.55;
  color: var(--ink-soft);
}
/* Under ~560px the disc costs more width than it earns - the statement is the
   point, and wrapping it around a 54px circle drops it to three or four words a
   line. Stack instead. */
@media (max-width: 560px) {
  .banner__in { flex-direction: column; align-items: flex-start; gap: 14px; }
  .banner__mark { width: 44px; height: 44px; }
  .banner__mark svg { width: 24px; height: 24px; }
}

/* ---------------------------------------------------------------- footer
   Four columns now, because the twelve service links live in the footer. That
   is what guarantees each detail page has inbound links from every page on the
   site - hand-maintaining twelve links in a footer is how orphans happen. */
.ftr__logo { width: 100%; max-width: 250px; margin-bottom: 16px; }
.ftr__h3-2 { margin-top: 26px; }
.ftr__grid--4 { grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); }
.ftr__links--tight a { padding-block: 3px; font-size: .92rem; }
