/* ==========================================================================
   PG Gardening & Tree Surgeon — site styles
   Plain CSS. No build step, no preprocessor.
   Palette: fresh mid green, near-white grounds with a faint green bias,
   and a warm gold used for the guarantee mark.
   All text/background pairs checked for WCAG AA (4.5:1 body, 3:1 large).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Brand — a lighter, fresher green than the original forest palette */
  --green-900: #0f3a26;   /* dark sections and headings */
  --green-800: #1b6f42;   /* primary: white text passes AA at 6.2:1 */
  --green-700: #22804f;   /* hover, brighter */
  --green-600: #34a06a;   /* fresh highlight */
  --green-100: #d9f2e4;
  --green-050: #eefaf3;

  /* Warm gold, used for the guarantee mark and small accents */
  --bark-800: #6b4f14;
  --bark-700: #7a5c1c;
  --bark-600: #8a5a12;    /* gold text on light: 5.9:1 */
  --bark-300: #f0c674;    /* gold on dark green: 7.9:1 */

  /* Light grounds with a faint green bias, instead of the old cream */
  --cream-050: #ffffff;
  --cream-100: #f4faf7;
  --cream-200: #eaf5ee;
  --cream-300: #dfeae4;

  --ink-900: #16241d;
  --ink-700: #35443c;
  --ink-500: #4a5a52;

  --white: #ffffff;
  --amber-600: #b8791c;
  --amber-100: #fdf3e2;
  --red-700: #a3231f;

  /* Semantic */
  --bg: var(--cream-100);
  --bg-raised: var(--white);
  --bg-sunken: var(--cream-200);
  --text: var(--ink-900);
  --text-muted: var(--ink-500);
  --brand: var(--green-800);
  --brand-strong: var(--green-900);
  --accent: var(--bark-600);
  --line: var(--cream-300);
  --line-strong: #c6dbcf;

  /* Type */
  --font-body: "Segoe UI", Roboto, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --font-display: Georgia, "Times New Roman", "Iowan Old Style", serif;

  /* Fluid scale */
  --step--1: clamp(0.83rem, 0.80rem + 0.15vw, 0.92rem);
  --step-0: clamp(1rem, 0.96rem + 0.20vw, 1.09rem);
  --step-1: clamp(1.19rem, 1.12rem + 0.34vw, 1.38rem);
  --step-2: clamp(1.41rem, 1.29rem + 0.58vw, 1.80rem);
  --step-3: clamp(1.65rem, 1.45rem + 0.95vw, 2.30rem);
  --step-4: clamp(1.95rem, 1.60rem + 1.60vw, 3.05rem);
  --step-5: clamp(2.25rem, 1.70rem + 2.60vw, 4.00rem);

  /* Space */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4rem;
  --sp-9: 6rem;

  /* Shape */
  --r-sm: 6px;
  --r-md: 12px;
  --r-lg: 20px;
  --r-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(15, 58, 38, 0.05), 0 2px 8px rgba(15, 58, 38, 0.04);
  --shadow-md: 0 4px 14px rgba(15, 58, 38, 0.07), 0 14px 32px rgba(15, 58, 38, 0.06);
  --shadow-lg: 0 10px 28px rgba(15, 58, 38, 0.09), 0 30px 64px rgba(15, 58, 38, 0.09);

  --wrap: 1180px;
  --wrap-narrow: 760px;

  --header-h: 80px;
  --callbar-h: 0px;
}

/* Fallback only — site.js measures the bar and overwrites this with its real
   height. Deliberately generous so nothing hides behind it before JS runs. */
@media (max-width: 860px) {
  :root { --callbar-h: 84px; }
}

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

/* The hidden attribute only carries `display: none` from the browser's own
   stylesheet, so any class that sets display — .card is flex, .grid is grid —
   silently beats it and the element stays on screen. Everything on this site
   that is shown and hidden from JavaScript uses the attribute, so it is worth
   settling once here rather than patching each component. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
  /* clip rather than hidden: stops sideways scroll without turning the root
     into a scroll container, which would break position: sticky. */
  overflow-x: clip;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  padding-bottom: var(--callbar-h);
  -webkit-font-smoothing: antialiased;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: 1.15;
  color: var(--brand-strong);
  margin: 0 0 var(--sp-4);
  font-weight: 700;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

h1 { font-size: var(--step-5); }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }

p, ul, ol, dl { margin: 0 0 var(--sp-4); }
p { max-width: 68ch; text-wrap: pretty; }

a { color: var(--green-800); text-underline-offset: 3px; }
a:hover { color: var(--green-700); }

:focus-visible {
  outline: 3px solid var(--amber-600);
  outline-offset: 2px;
  border-radius: 3px;
}

hr { border: 0; border-top: 1px solid var(--line); margin: var(--sp-6) 0; }

code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.9em;
  background: var(--cream-200);
  padding: 0.1em 0.35em;
  border-radius: 4px;
  overflow-wrap: anywhere;
}

strong { font-weight: 700; }

/* --------------------------------------------------------------------------
   3. Layout helpers
   -------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--sp-5);
}

.wrap--narrow { max-width: var(--wrap-narrow); }

.section { padding-block: clamp(3.5rem, 8vw, 7rem); }
.section--tight { padding-block: clamp(2.5rem, 5vw, 4rem); }
.section--cream { background: var(--cream-200); }
.section--white { background: var(--white); }
.section--dark {
  background:
    linear-gradient(160deg, rgba(27, 111, 66, 0.55) 0%, transparent 60%),
    radial-gradient(110% 95% at 12% 0%, rgba(52, 160, 106, 0.28) 0%, transparent 62%),
    var(--green-900);
  color: var(--cream-100);
}
.section--dark h2, .section--dark h3 { color: var(--white); }
.section--dark p { color: rgba(253, 250, 244, 0.88); }

.section-head { max-width: 60ch; margin-bottom: var(--sp-7); }
.section-head--centre { margin-inline: auto; text-align: center; }
.section-head--centre p { margin-inline: auto; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  /* the darker green: the lighter one falls to 4.4:1 on the tinted sections */
  color: var(--green-800);
  margin-bottom: var(--sp-3);
}
.eyebrow::before {
  content: "";
  width: 26px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
}
.section--dark .eyebrow { color: #cfeadd; }
.section--dark .eyebrow::before { background: var(--bark-300); }

.lede { font-size: var(--step-1); color: var(--ink-700); }
.section--dark .lede { color: rgba(253, 250, 244, 0.9); }

.grid { display: grid; gap: var(--sp-6); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr)); }

/* Moved vertically out of view rather than off to the side, so it can never
   widen the page. */
.skip-link {
  position: absolute;
  left: 0;
  top: 0;
  transform: translateY(-150%);
  background: var(--green-900);
  color: var(--white);
  padding: var(--sp-3) var(--sp-4);
  z-index: 200;
  border-radius: 0 0 var(--r-sm) 0;
  transition: transform 0.15s ease;
}
.skip-link:focus { transform: translateY(0); }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 700;
  line-height: 1.2;
  padding: 0.85em 1.5em;
  border-radius: var(--r-pill);
  border: 2px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.16s ease, background-color 0.16s ease, box-shadow 0.16s ease, color 0.16s ease;
  min-height: 48px;
  text-align: center;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--primary { background: var(--green-800); color: var(--white); box-shadow: var(--shadow-sm); }
.btn--primary:hover { background: var(--green-700); color: var(--white); box-shadow: var(--shadow-md); }

.btn--accent { background: var(--bark-600); color: var(--white); box-shadow: var(--shadow-sm); }
.btn--accent:hover { background: var(--bark-700); color: var(--white); box-shadow: var(--shadow-md); }

.btn--ghost { background: transparent; color: var(--green-800); border-color: var(--green-800); }
.btn--ghost:hover { background: var(--green-800); color: var(--white); }

.btn--light { background: var(--white); color: var(--green-900); }
.btn--light:hover { background: var(--cream-100); color: var(--green-900); }

.btn--outline-light { background: transparent; color: var(--white); border-color: rgba(255,255,255,0.6); }
.btn--outline-light:hover { background: rgba(255,255,255,0.12); color: var(--white); border-color: var(--white); }

.btn--wide { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

/* Light surfaces sitting inside dark ones ------------------------------------
   A white card, a notice or a light button inside a dark section or the footer
   is its own light surface — but it still inherits the dark context's
   light-on-dark text colours, and those rules out-specify the plain element
   ones. Left alone it prints white on white: card headings vanish outright,
   tick lists with them, and the footer's white button comes out blank.
   Each block below puts the light-background palette back. */
.section--dark .card,
.section--dark .notice { color: var(--text); }

.section--dark .card h2, .section--dark .card h3, .section--dark .card h4,
.section--dark .notice h2, .section--dark .notice h3, .section--dark .notice h4 {
  color: var(--brand-strong);
}
.section--dark .card p, .section--dark .card .lede,
.section--dark .notice p, .section--dark .notice .lede { color: var(--ink-700); }

.section--dark .card a, .section--dark .notice a { color: var(--green-800); }
.section--dark .card .eyebrow, .section--dark .notice .eyebrow { color: var(--green-800); }
.section--dark .card .eyebrow::before,
.section--dark .notice .eyebrow::before { background: var(--accent); }

/* The footer's link colour is meant for links. A button brings its own
   background, so it has to bring its own text colour with it. */
.site-footer .btn--light, .site-footer .btn--light:hover { color: var(--green-900); }
.site-footer .btn--primary, .site-footer .btn--primary:hover,
.site-footer .btn--outline-light, .site-footer .btn--outline-light:hover { color: var(--white); }

/* --------------------------------------------------------------------------
   5. Header / navigation
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}
.site-header.is-scrolled { box-shadow: var(--shadow-sm); }

/* The header carries more across it than a content column does — brand, seven
   links, two numbers and a button — so it runs wider than the text measure. */
.site-header .wrap { max-width: 1320px; }

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  min-height: var(--header-h);
  min-width: 0;
}

.brand {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  color: var(--green-900);
  min-width: 0;
}
/* The logo sits straight on the header with no plate behind it. Its "PG" and
   "& TREE SURGEON" are near-white, so a soft dark shadow gives those two
   parts an edge to read against — the artwork carries its own shadow already,
   this only deepens it. Nothing is recoloured. */
.brand__logo {
  display: block;
  flex-shrink: 0;
  width: clamp(158px, 18vw, 228px);
  height: auto;
  filter:
    drop-shadow(0 0 1px rgba(15, 58, 38, 0.85))
    drop-shadow(0 0 1px rgba(15, 58, 38, 0.85));
}
/* Still used by the footer, which sets the name in type rather than artwork. */
.nav-toggle {
  display: none;
  align-items: center;
  gap: var(--sp-2);
  background: var(--white);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  padding: 0.55rem 0.9rem;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--green-900);
  cursor: pointer;
  min-height: 44px;
}
.nav-toggle__bars { display: grid; gap: 4px; width: 18px; flex-shrink: 0; }
.nav-toggle__bars span {
  display: block;
  height: 2px;
  background: var(--green-900);
  border-radius: 2px;
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.nav { display: flex; align-items: center; gap: var(--sp-1); min-width: 0; }
.nav__list {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  list-style: none;
  margin: 0;
  padding: 0;
  /* Never let the link row squash below its content: it would overflow its
     own box and print on top of whatever sits to the right of it. */
  flex-shrink: 0;
}
.nav__link {
  display: inline-block;
  padding: 0.55rem 0.7rem;
  border-radius: var(--r-sm);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink-700);
  text-decoration: none;
  white-space: nowrap;
}
.nav__link:hover { background: var(--green-050); color: var(--green-800); }
.nav__link[aria-current="page"] {
  color: var(--green-800);
  background: var(--green-050);
  box-shadow: inset 0 -2px 0 var(--green-700);
}

/* Phone links, written in by tools/setup.mjs once the real numbers exist. */
.tel {
  text-decoration: none;
  color: inherit;
  white-space: nowrap;
}
.tel:hover strong { text-decoration: underline; }
.tel__label {
  font-size: 0.85em;
  opacity: 0.8;
  font-weight: 600;
}
.header-phones .tel { font-size: 0.85rem; color: var(--ink-700); }
.header-phones .tel strong { color: var(--green-800); }
.site-footer .tel strong { color: var(--white); }

.header-cta { display: flex; align-items: center; gap: var(--sp-3); flex-shrink: 0; }
.header-phones {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: right;
  font-size: 0.85rem;
  max-width: 210px;
  overflow: hidden;
}
.header-phones .pending { font-size: 0.72rem; }

/* The two numbers only fit alongside a seven-item nav on a wide screen. */
@media (max-width: 1240px) {
  .header-phones { display: none; }
}

/* Collapse to the burger while the full nav still fits comfortably, rather
   than at the width where it starts to overflow. */
@media (max-width: 1100px) {
  .nav-toggle { display: inline-flex; }
  .nav {
    position: fixed;
    /* The header sets backdrop-filter, and that makes it the containing block
       for any fixed-position child — so these offsets resolve against the
       header, not the viewport. Anchoring the panel to the bottom of the
       header and giving it an explicit height is what stops it collapsing to
       a sliver with the menu scrolling inside it.
       dvh second so it wins where supported: it accounts for the phone
       browser's own address bar, which vh does not. */
    inset: 100% 0 auto 0;
    height: calc(100vh - var(--header-h));
    height: calc(100dvh - var(--header-h));
    background: var(--cream-050);
    display: none;
    padding: var(--sp-5);
    /* The sticky call bar sits on top of this panel, so the last thing in the
       menu — the quote button — has to be able to scroll clear of it.
       --callbar-h is 0 above the width where the bar appears. */
    padding-bottom: calc(var(--sp-5) + var(--callbar-h));
    overflow-y: auto;
    /* Scrolling to the bottom of the menu must not then start scrolling the
       page underneath it. This is what the body lock used to be for. */
    overscroll-behavior: contain;
    border-top: 1px solid var(--line);
  }
  /* Shown by toggling display, so the closed menu is never laid out
     off-screen and can never widen the page. */
  .nav.is-open { display: block; animation: nav-in 0.22s ease both; }
  .nav__list { flex-direction: column; align-items: stretch; gap: 2px; }
  .nav__link {
    display: block;
    padding: var(--sp-4);
    font-size: 1.05rem;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
  }
  .nav__cta { margin-top: var(--sp-5); display: grid; gap: var(--sp-3); }
  .header-cta .btn--primary { display: none; }
}

/* Small phones: the logo comes down a size so it never pushes the burger off
   the screen. */
@media (max-width: 560px) {
  .brand__logo { width: 150px; }
}

@media (max-width: 430px) {
  .brand__logo { width: 148px; }
  .nav-toggle { padding: 0.55rem 0.7rem; }
  /* Clipped, not display:none, so the button keeps its accessible name. */
  .nav-toggle__text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

@keyframes nav-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}

@media (min-width: 1101px) {
  .nav__cta { display: none; }
}

/* The menu used to lock the page with `body { overflow: hidden }`. Do not put
   that back. Hiding the body's overflow takes the body out of the scrolling
   picture, and two things follow at once: the browser drops the scroll
   position to the top, and the sticky header stops sticking — so it snaps back
   to the top of the document, taking the menu panel anchored beneath it with
   it. Open the menu half way down a page and the menu was rendering hundreds
   of pixels above the screen, invisible, while the page jumped to the top.
   The panel handles its own scrolling and uses overscroll-behavior instead. */
body.nav-open { overflow: visible; }

/* --------------------------------------------------------------------------
   6. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  color: var(--cream-050);
  background:
    linear-gradient(155deg, rgba(27, 111, 66, 0.88) 0%, rgba(20, 88, 56, 0.93) 48%, rgba(15, 58, 38, 0.96) 100%),
    radial-gradient(80% 65% at 78% 6%, rgba(52, 160, 106, 0.50) 0%, transparent 72%),
    var(--green-800);
  overflow: hidden;
  isolation: isolate;
}
/* The hero photograph. It sits behind the type at full strength and is
   darkened by the scrim below rather than by its own opacity, which keeps the
   branded kit and the chipper readable instead of washing the whole thing out.
   Decorative here: it is a backdrop to the headline, and announcing it ahead
   of the headline would only get in the way. */
.hero__media {
  position: absolute;
  inset: 0;
  z-index: -1;
  object-fit: cover;
  object-position: 58% 26%;
  width: 100%;
  height: 100%;
}
/* The scrim. Heaviest on the left, where the headline sits, easing off to the
   right so the climber and the van stay visible. Measured, not guessed — the
   hero text is checked against the rendered pixels, not the stylesheet. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(100deg,
    rgba(15, 58, 38, 0.95) 0%,
    rgba(15, 58, 38, 0.88) 34%,
    rgba(15, 58, 38, 0.58) 64%,
    rgba(15, 58, 38, 0.38) 100%);
}
/* Stacked on a phone the type runs the full width, so the scrim runs top-down
   instead and lets the photograph through underneath the buttons. */
@media (max-width: 900px) {
  .hero::after {
    background: linear-gradient(178deg,
      rgba(15, 58, 38, 0.78) 0%,
      rgba(15, 58, 38, 0.68) 55%,
      rgba(15, 58, 38, 0.42) 100%);
  }
  /* Panned left so the climber and the branded shirt are what fills a narrow
     screen, rather than a slice of tree trunk. */
  .hero__media { object-position: 38% 26%; }
}
.hero__inner {
  padding-block: clamp(3.5rem, 9vw, 7rem);
  display: grid;
  gap: var(--sp-7);
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: center;
}
@media (max-width: 900px) {
  .hero__inner { grid-template-columns: 1fr; gap: var(--sp-6); }
}

/* On a phone the headline was running to four lines and taking a third of the
   screen, which pushed the quote button off the bottom. Tighter type and less
   padding gets the eyebrow, headline, promise and both buttons onto the first
   screen, which is the whole job of a landing page. */
@media (max-width: 560px) {
  .hero__inner { padding-block: clamp(1.75rem, 6vw, 3rem); gap: var(--sp-5); }
  .hero h1 { font-size: clamp(1.9rem, 1.1rem + 4.6vw, 2.4rem); line-height: 1.1; }
  .hero__lede { font-size: 1.03rem; margin-bottom: var(--sp-4); }
  /* Sized so the towns sit on one line rather than orphaning a word. */
  .hero .eyebrow { margin-bottom: var(--sp-2); font-size: 0.76rem; letter-spacing: 0.06em; }
}
.hero h1 { color: var(--white); margin-bottom: var(--sp-4); }
.hero h1 em {
  font-style: normal;
  color: var(--bark-300);
  display: block;
}
.hero__lede {
  font-size: var(--step-1);
  color: rgba(253, 250, 244, 0.92);
  max-width: 52ch;
  margin-bottom: var(--sp-5);
}
.hero .eyebrow { color: #cfeadd; }
.hero .eyebrow::before { background: var(--bark-300); }

.hero__points {
  list-style: none;
  padding: 0;
  margin: var(--sp-5) 0 0;
  display: grid;
  gap: var(--sp-2);
}
.hero__points li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  color: rgba(253, 250, 244, 0.92);
  font-size: 0.98rem;
}
.hero__points svg { flex-shrink: 0; margin-top: 3px; color: var(--bark-300); }

/* Hero side card */
.quote-card {
  background: var(--cream-050);
  color: var(--text);
  border-radius: var(--r-lg);
  padding: var(--sp-6);
  box-shadow: var(--shadow-lg);
  border: 1px solid rgba(255,255,255,0.4);
}
.quote-card h2 { font-size: var(--step-2); margin-bottom: var(--sp-2); }
.quote-card p { font-size: 0.95rem; color: var(--ink-700); }

/* --------------------------------------------------------------------------
   7. Cards
   -------------------------------------------------------------------------- */
.card {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-5);
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
  display: flex;
  flex-direction: column;
}
.card h3 { margin-bottom: var(--sp-2); }
.card p { font-size: 0.97rem; color: var(--ink-700); margin-bottom: var(--sp-4); }
.card > :last-child { margin-top: auto; margin-bottom: 0; }

a.card, .card--link { text-decoration: none; color: inherit; }
a.card:hover, .card--link:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: var(--green-100);
}

.card__icon {
  width: 52px;
  height: 52px;
  border-radius: var(--r-md);
  background: var(--green-050);
  color: var(--green-800);
  display: grid;
  place-items: center;
  margin-bottom: var(--sp-4);
  flex-shrink: 0;
}
.card__more {
  font-weight: 700;
  color: var(--green-800);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: 0.95rem;
}
a.card:hover .card__more { gap: var(--sp-3); }
.card__more svg { transition: transform 0.2s ease; }
a.card:hover .card__more svg { transform: translateX(3px); }

/* Service card with photo slot */
.service-card { padding: 0; overflow: hidden; }
.service-card__media {
  aspect-ratio: 16 / 10;
  background: var(--cream-200);
  position: relative;
  overflow: hidden;
}
.service-card__media img { width: 100%; height: 100%; object-fit: cover; }
.service-card__body { padding: var(--sp-5); display: flex; flex-direction: column; flex: 1; }

/* Tick list */
.ticks { list-style: none; padding: 0; margin: 0 0 var(--sp-4); display: grid; gap: var(--sp-2); }
/* The tick hangs in a left gutter rather than sitting as a flex item. As a
   flex row the item's own ::before, a leading <strong> and the text after it
   all became separate flex items, so "£2 million public liability insurance."
   was squeezed into its own narrow column beside its own sentence. Twenty-nine
   list items across the site open with a bold lead-in like that. */
.ticks li {
  position: relative;
  padding-left: calc(20px + var(--sp-3));
  font-size: 0.97rem;
}
.ticks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--green-050);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231b6f42' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-size: 13px;
  background-repeat: no-repeat;
  background-position: center;
}
.section--dark .ticks li::before {
  background-color: rgba(255,255,255,0.14);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23f0c674' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
}
.ticks--2col { grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); gap: var(--sp-2) var(--sp-5); }

/* Steps */
.steps { counter-reset: step; display: grid; gap: var(--sp-5); list-style: none; padding: 0; margin: 0; }
.steps--row { grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); }
.step {
  position: relative;
  padding-left: 62px;
  counter-increment: step;
}
.step::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--green-800);
  color: var(--white);
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
}
.step h3 { font-size: var(--step-1); margin-bottom: var(--sp-2); padding-top: 6px; }
.step p { font-size: 0.97rem; color: var(--ink-700); margin: 0; }

/* On the dark green band the step text was unreadable: .step p sets --ink-700,
   a near-black meant for cream backgrounds, and it is declared after
   `.section--dark p` at the same specificity, so it won. That put #35443c on
   #0f3a26 — a contrast ratio of 1.24:1, where 4.5:1 is the floor for body
   text. Not dim, invisible. Cream takes it to 12:1.
   The number badge gets the palette's gold, which reads at 7.9:1 against the
   dark green and separates the badge from the band behind it. */
.section--dark .step p { color: var(--cream-100); }
.section--dark .step::before { background: var(--bark-300); color: var(--green-900); }

/* Notice / callout */
.notice {
  border-left: 4px solid var(--amber-600);
  background: var(--amber-100);
  padding: var(--sp-5);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  margin-block: var(--sp-5);
}
.notice h3 { font-size: var(--step-1); margin-bottom: var(--sp-2); color: var(--bark-800); }
.notice p:last-child, .notice ul:last-child { margin-bottom: 0; }

.notice--green { border-left-color: var(--green-700); background: var(--green-050); }
.notice--green h3 { color: var(--green-900); }

/* Pending-information marker (used until the owner supplies real details) */
.pending {
  display: inline-block;
  background: repeating-linear-gradient(45deg, #fff5d6, #fff5d6 8px, #ffeeba 8px, #ffeeba 16px);
  border: 1px dashed var(--amber-600);
  color: var(--bark-800);
  border-radius: var(--r-sm);
  padding: 0.1em 0.5em;
  font-size: 0.92em;
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   8. Before / after slider
   -------------------------------------------------------------------------- */
.ba {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.ba__frame {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--cream-200);
  touch-action: pan-y;
  user-select: none;
  cursor: ew-resize;
}
.ba__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ba__after-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  clip-path: inset(0 0 0 var(--pos, 50%));
}
.ba__handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos, 50%);
  width: 4px;
  margin-left: -2px;
  background: var(--white);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.18);
  pointer-events: none;
}
.ba__grip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: var(--white);
  box-shadow: var(--shadow-md);
  display: grid;
  place-items: center;
  color: var(--green-900);
}
.ba__range {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  margin: 0;
  cursor: ew-resize;
}
.ba__range:focus-visible + .ba__handle .ba__grip { outline: 3px solid var(--amber-600); outline-offset: 3px; }

.ba__tag {
  position: absolute;
  top: var(--sp-3);
  padding: 0.3rem 0.7rem;
  border-radius: var(--r-pill);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--white);
  background: rgba(15, 58, 38, 0.80);
  pointer-events: none;
}
.ba__tag--before { left: var(--sp-3); }
.ba__tag--after { right: var(--sp-3); background: rgba(138, 90, 18, 0.88); }

.ba__caption { padding: var(--sp-4) var(--sp-5); border-top: 1px solid var(--line); }
.ba__caption h3 { font-size: var(--step-1); margin-bottom: var(--sp-1); }
.ba__caption p { font-size: 0.92rem; color: var(--ink-500); margin: 0; }

/* --------------------------------------------------------------------------
   9. Photo slots / gallery
   -------------------------------------------------------------------------- */
/* Before/after sliders need room to be draggable — two across on a desktop,
   not four postage stamps. */
.ba-grid {
  display: grid;
  gap: var(--sp-5);
  grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
}

.slot {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 140px;
  height: 100%;
  overflow: hidden;
  background:
    repeating-linear-gradient(45deg, var(--cream-200), var(--cream-200) 12px, var(--cream-300) 12px, var(--cream-300) 24px);
  color: var(--bark-700);
  text-align: center;
  padding: var(--sp-4) var(--sp-3);
}
.slot__inner { max-width: 34ch; }
.slot__label {
  font-weight: 700;
  font-size: 0.88rem;
  display: block;
  margin-bottom: var(--sp-1);
  color: var(--bark-800);
  line-height: 1.25;
}
.slot__hint {
  font-size: 0.72rem;
  line-height: 1.4;
  color: var(--bark-700);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  word-break: break-all;
}
.slot__icon { margin: 0 auto var(--sp-2); color: var(--bark-600); }

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(clamp(240px, 30vw, 320px), 100%), 1fr));
  gap: var(--sp-4);
}
.photo {
  position: relative;
  margin: 0;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--cream-200);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.photo:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.photo__btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}
.photo img { aspect-ratio: 4 / 3; object-fit: cover; width: 100%; }
.photo figcaption {
  padding: var(--sp-3) var(--sp-4);
  font-size: 0.88rem;
  color: var(--ink-700);
  border-top: 1px solid var(--line);
  background: var(--white);
  text-align: left;
}

/* Filter chips */
.filters { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-6); }
.chip {
  font: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  padding: 0.5rem 1rem;
  min-height: 44px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-strong);
  background: var(--white);
  color: var(--ink-700);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.chip:hover { border-color: var(--green-700); color: var(--green-800); }
.chip[aria-pressed="true"] { background: var(--green-800); border-color: var(--green-800); color: var(--white); }

/* Lightbox */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(11, 26, 19, 0.94);
  display: grid;
  place-items: center;
  padding: var(--sp-5);
}
.lightbox__img {
  max-width: min(1100px, 94vw);
  max-height: 82vh;
  width: auto;
  object-fit: contain;
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-lg);
}
.lightbox__cap {
  color: var(--cream-100);
  text-align: center;
  margin-top: var(--sp-4);
  font-size: 0.95rem;
  max-width: 60ch;
}
.lightbox__close, .lightbox__nav {
  position: absolute;
  background: rgba(255,255,255,0.14);
  border: 1px solid rgba(255,255,255,0.32);
  color: var(--white);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  cursor: pointer;
  font-size: 1.3rem;
  line-height: 1;
}
.lightbox__close:hover, .lightbox__nav:hover { background: rgba(255,255,255,0.28); }
.lightbox__close { top: var(--sp-5); right: var(--sp-5); }
.lightbox__nav--prev { left: var(--sp-4); top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: var(--sp-4); top: 50%; transform: translateY(-50%); }


/* --------------------------------------------------------------------------
   9b. Guarantee seal
   -------------------------------------------------------------------------- */
.seal {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-5) var(--sp-6);
  box-shadow: var(--shadow-sm);
}
.seal__mark { width: 128px; height: 128px; flex-shrink: 0; }
.seal__text h3 { font-size: var(--step-1); margin-bottom: var(--sp-2); }
.seal__text p { font-size: 0.95rem; color: var(--ink-700); margin: 0; }

.seal--dark {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(240, 198, 116, 0.35);
  box-shadow: none;
}
.seal--dark .seal__text h3 { color: var(--bark-300); }
.seal--dark .seal__text p { color: rgba(255, 255, 255, 0.88); }

/* Small version that sits in the hero next to the headline */
.seal--inline {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(240, 198, 116, 0.4);
  border-radius: var(--r-pill);
  padding: 0.4rem 1rem 0.4rem 0.4rem;
  box-shadow: none;
}
.seal--inline .seal__mark { width: 42px; height: 42px; }
.seal--inline span {
  font-size: 0.88rem;
  font-weight: 700;
  color: #ffffff;
  letter-spacing: 0.02em;
}

@media (max-width: 520px) {
  /* The big seal block stacks on a phone. The inline pill in the hero shares
     the .seal class but is a badge-and-label lock-up, not a block — stacking
     it left the tick floating above its own caption. */
  .seal:not(.seal--inline) { flex-direction: column; text-align: center; gap: var(--sp-4); }
  /* The badge is not shrunk on phones. It carries type inside it, and scaling
     the badge down scales the words down with it. */
}

/* --------------------------------------------------------------------------
   10. Reviews
   -------------------------------------------------------------------------- */
.review {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-left: 4px solid var(--green-700);
  border-radius: var(--r-md);
  padding: var(--sp-5);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
/* "See my certificates" in the hero. The claim about insurance and tickets
   sits in the list above; this is the invitation to go and check it, and it was
   previously an inline link inside a bullet where nobody was going to find it.
   Given its own row, on the pale gold used for the guarantee mark so it reads
   as proof rather than as a third call to action competing with the quote
   button. */
.hero__proof { margin: var(--sp-5) 0 0; }
.btn--proof {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 0.85rem 1.4rem;
  border-radius: var(--r-pill);
  background: var(--bark-300);
  color: var(--green-900);
  text-decoration: none;
  font-family: var(--font-body);
  box-shadow: var(--shadow-sm);
  min-height: 56px;
}
.btn--proof:hover, .btn--proof:focus-visible { background: #f6d590; color: var(--green-900); }
.btn--proof svg { flex-shrink: 0; }
.btn--proof span { display: flex; flex-direction: column; line-height: 1.25; }
.btn--proof strong { font-size: 1.06rem; font-weight: 700; }
.btn--proof small { font-size: 0.86rem; color: var(--bark-800); }

/* The certificate video. Filmed on a phone, so it is portrait — capped by
   height rather than width, or a 9:16 clip becomes a column of video with the
   page scrolled away either side of it on a desktop. */
.cert-video { margin: 0 0 var(--sp-6); display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); }
.cert-video video {
  /* Match the clip's own 9:16 exactly. Sizing by width alone and capping the
     height leaves the player wider than the picture, which shows as black bars
     down both sides. */
  aspect-ratio: 576 / 1024;
  height: min(72vh, 620px);
  width: auto;
  max-width: 100%;
  border-radius: var(--r-md);
  background: #000;
  box-shadow: var(--shadow-md);
}
.cert-video figcaption {
  font-size: 0.92rem;
  color: var(--text-muted);
  text-align: center;
  max-width: 46ch;
}

.review__stars { color: var(--bark-600); letter-spacing: 2px; font-size: 1.05rem; }
.review__text { font-size: 1rem; color: var(--ink-700); margin: 0; flex: 1; }
.review__meta { font-size: 0.88rem; color: var(--ink-500); margin: 0; }
.review__meta strong { color: var(--ink-900); display: block; font-size: 0.95rem; }

.reviews-cta {
  display: grid;
  gap: var(--sp-5);
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  align-items: stretch;
}
.reviews-empty {
  border: 2px dashed var(--line-strong);
  border-radius: var(--r-md);
  padding: var(--sp-6);
  text-align: center;
  background: var(--cream-050);
}

/* --------------------------------------------------------------------------
   11. Forms
   -------------------------------------------------------------------------- */
.form { display: grid; gap: var(--sp-4); }
.field { display: grid; gap: var(--sp-2); }
.field label { font-weight: 700; font-size: 0.95rem; color: var(--ink-900); }
.field .hint { font-size: 0.85rem; color: var(--ink-500); font-weight: 400; }
.field .req { color: var(--red-700); }

input[type="text"], input[type="email"], input[type="tel"], select, textarea {
  font: inherit;
  font-size: 1rem;
  width: 100%;
  padding: 0.8rem 0.9rem;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--white);
  color: var(--ink-900);
  min-height: 48px;
}
textarea { min-height: 140px; resize: vertical; }
input:focus, select:focus, textarea:focus { border-color: var(--green-700); }
::placeholder { color: #7b8a83; }

.field--half-row { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); }

.checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  font-size: 0.92rem;
  color: var(--ink-700);
}
.checkbox-row input { width: 22px; height: 22px; min-height: 22px; margin-top: 2px; flex-shrink: 0; accent-color: var(--green-800); }

/* Honeypot: clipped rather than pushed off-screen, so it takes up no layout
   space in any direction. Still reachable by bots reading the DOM. */
.hp-field {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.form-note { font-size: 0.85rem; color: var(--ink-500); }

/* Postcode checker ---------------------------------------------------------
   The answer is colour-coded, but the colour only repeats what the words
   already say — nobody has to tell green from amber to understand it. */
.area-check__form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}
.area-check__form .field { flex: 1 1 11rem; margin: 0; }
.area-check__form input { text-transform: uppercase; }
.area-check__form .btn { flex: 0 0 auto; }

.area-check__result {
  margin: var(--sp-4) 0 0;
  padding: var(--sp-4);
  border-radius: var(--r-sm);
  border-left: 4px solid var(--line-strong);
  background: var(--cream-200);
  color: var(--ink-900);
  font-size: 0.95rem;
}
.area-check__result.is-yes { background: var(--green-050); border-left-color: var(--green-700); }
.area-check__result.is-maybe { background: var(--amber-100); border-left-color: var(--amber-600); }
.area-check__result.is-no,
.area-check__result.is-error { background: var(--cream-200); border-left-color: var(--ink-500); }

@media (max-width: 420px) {
  .area-check__form .btn { width: 100%; }
}

/* The customer's own words, carried from the review form to the thank-you page
   so they can paste them onto Google without retyping. */
.review-carry {
  margin: var(--sp-4) 0;
  padding: var(--sp-4) var(--sp-5);
  background: var(--white);
  border-left: 3px solid var(--green-600);
  border-radius: var(--r-sm);
  font-size: 0.98rem;
  color: var(--ink-900);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 14rem;
  overflow-y: auto;
}
.btn.is-done { background: var(--green-100); border-color: var(--green-600); color: var(--green-900); }

/* --------------------------------------------------------------------------
   12. Areas
   -------------------------------------------------------------------------- */
.area-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr));
  gap: var(--sp-3);
  list-style: none;
  padding: 0;
  margin: 0;
}
.area-list a {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  text-decoration: none;
  font-weight: 600;
  color: var(--green-900);
  min-height: 48px;
  transition: border-color 0.15s ease, transform 0.15s ease, background-color 0.15s ease;
}
.area-list a:hover { border-color: var(--green-700); background: var(--green-050); transform: translateX(2px); }
.area-list a svg { color: var(--green-700); flex-shrink: 0; }

.pill-list { display: flex; flex-wrap: wrap; gap: var(--sp-2); list-style: none; padding: 0; margin: 0; }
.pill-list li {
  background: var(--green-050);
  color: var(--green-900);
  border: 1px solid var(--green-100);
  border-radius: var(--r-pill);
  padding: 0.35rem 0.85rem;
  font-size: 0.9rem;
  font-weight: 600;
}
.section--dark .pill-list li {
  background: rgba(255,255,255,0.1);
  border-color: rgba(255,255,255,0.2);
  color: var(--cream-100);
}

/* --------------------------------------------------------------------------
   13. FAQ
   -------------------------------------------------------------------------- */
.faq { display: grid; gap: var(--sp-3); max-width: 820px; }
.faq details {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
}
.faq details[open] { border-color: var(--green-100); box-shadow: var(--shadow-sm); }
.faq summary {
  cursor: pointer;
  list-style: none;
  padding: var(--sp-4) var(--sp-5);
  padding-right: 56px;
  font-weight: 700;
  font-size: 1.02rem;
  color: var(--green-900);
  position: relative;
  min-height: 48px;
  display: flex;
  align-items: center;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  position: absolute;
  right: var(--sp-5);
  top: 50%;
  width: 14px;
  height: 14px;
  margin-top: -7px;
  border-right: 2.5px solid var(--green-700);
  border-bottom: 2.5px solid var(--green-700);
  transform: rotate(45deg);
  transition: transform 0.2s ease;
}
.faq details[open] summary::after { transform: rotate(-135deg); margin-top: -3px; }
.faq .faq__body { padding: 0 var(--sp-5) var(--sp-5); }
.faq .faq__body p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   14. Breadcrumbs, prose, tables
   -------------------------------------------------------------------------- */
.crumbs { font-size: 0.87rem; padding-block: var(--sp-4); color: var(--ink-500); }
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: var(--sp-2); padding: 0; margin: 0; }
.crumbs li::after { content: "›"; margin-left: var(--sp-2); color: var(--line-strong); }
.crumbs li:last-child::after { content: ""; }
.crumbs a { color: var(--ink-500); }
.crumbs [aria-current="page"] { color: var(--ink-900); font-weight: 600; }

.prose h2 { font-size: var(--step-3); margin-top: var(--sp-7); }
.prose h3 { font-size: var(--step-1); margin-top: var(--sp-6); }
.prose > :first-child { margin-top: 0; }
.prose ul, .prose ol { padding-left: 1.3em; }
.prose li { margin-bottom: var(--sp-2); max-width: 68ch; }

.table-scroll { overflow-x: auto; margin-bottom: var(--sp-5); }
table { border-collapse: collapse; width: 100%; min-width: 480px; font-size: 0.95rem; }
th, td { text-align: left; padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--line); vertical-align: top; }
th { background: var(--cream-200); font-weight: 700; color: var(--green-900); }

/* --------------------------------------------------------------------------
   15. CTA band
   -------------------------------------------------------------------------- */
.cta-band {
  background:
    linear-gradient(135deg, rgba(15, 58, 38, 0.96) 0%, rgba(27, 111, 66, 0.94) 100%),
    var(--green-900);
  color: var(--cream-050);
  border-radius: var(--r-lg);
  padding: clamp(1.75rem, 4vw, 3rem);
  display: grid;
  gap: var(--sp-5);
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  align-items: center;
  box-shadow: var(--shadow-md);
}
@media (max-width: 780px) { .cta-band { grid-template-columns: 1fr; } }
.cta-band h2 { color: var(--white); font-size: var(--step-3); margin-bottom: var(--sp-2); }
.cta-band p { color: rgba(253, 250, 244, 0.9); margin: 0; }
.cta-band__actions { display: grid; gap: var(--sp-3); }

/* --------------------------------------------------------------------------
   16. Footer
   -------------------------------------------------------------------------- */
.site-footer {
  background: var(--green-900);
  color: rgba(253, 250, 244, 0.82);
  padding-block: var(--sp-7) var(--sp-5);
  font-size: 0.94rem;
}
.site-footer h3 {
  color: var(--white);
  font-family: var(--font-body);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: var(--sp-4);
}
.footer-grid {
  display: grid;
  gap: var(--sp-6);
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  padding-bottom: var(--sp-6);
  border-bottom: 1px solid rgba(255,255,255,0.14);
}
.site-footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-2); }
.site-footer a { color: rgba(253, 250, 244, 0.86); text-decoration: none; }
.site-footer a:hover { color: var(--white); text-decoration: underline; }
/* The footer is already the dark green the logo was drawn for, so it goes in
   plainly here — no shadow needed, unlike the light header. */
.footer-brand__logo { width: min(240px, 80%); height: auto; margin-bottom: var(--sp-3); }
.footer-brand .brand__strap {
  display: block;
  color: var(--bark-300);
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 600;
}
.footer-bottom {
  padding-top: var(--sp-5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-5);
  justify-content: space-between;
  font-size: 0.85rem;
  color: rgba(253, 250, 244, 0.65);
}
.footer-social { display: flex; gap: var(--sp-3); margin-top: var(--sp-4); }
.footer-social a {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(255,255,255,0.1);
  border: 1px solid rgba(255,255,255,0.18);
  color: var(--white);
}
.footer-social a:hover { background: rgba(255,255,255,0.2); }

.footer-contact li { display: flex; align-items: flex-start; gap: var(--sp-3); }
.footer-contact svg { flex-shrink: 0; margin-top: 4px; color: var(--bark-300); }

/* --------------------------------------------------------------------------
   17. Sticky mobile call bar
   -------------------------------------------------------------------------- */
.callbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 120;
  display: none;
  gap: 1px;
  background: rgba(15, 58, 38, 0.18);
  box-shadow: 0 -4px 18px rgba(0,0,0,0.16);
  padding-bottom: env(safe-area-inset-bottom, 0);
}
@media (max-width: 860px) { .callbar { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; } }
/* Direct children only: the labels nested inside each cell are plain text and
   must not inherit the cell's own box. */
.callbar > a, .callbar > span {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  min-height: 60px;
  padding: var(--sp-2) var(--sp-1);
  text-decoration: none;
  font-size: 0.78rem;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  background: var(--green-800);
  color: var(--white);
  overflow: hidden;
}
.callbar > a:active { background: var(--green-700); }
.callbar .callbar--quote { background: var(--bark-600); }
.callbar a span, .callbar small {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The number itself, on the one control that matters most on a phone. It was
   10.9px at 90% opacity — legible, but not for the customer squinting at it
   in a garden. Full opacity and up to about 12.5px. */
.callbar small { font-weight: 400; font-size: 0.78rem; opacity: 1; }
.callbar svg { margin-bottom: 1px; }

/* --------------------------------------------------------------------------
   18. Cookie banner
   -------------------------------------------------------------------------- */
.cookie-banner {
  position: fixed;
  z-index: 200;
  left: var(--sp-4);
  right: var(--sp-4);
  bottom: calc(var(--callbar-h) + var(--sp-4));
  max-width: 560px;
  margin-inline: auto;
  background: var(--cream-050);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  padding: var(--sp-5);
}
.cookie-banner h2 { font-size: var(--step-1); margin-bottom: var(--sp-2); }
.cookie-banner p { font-size: 0.92rem; margin-bottom: var(--sp-4); color: var(--ink-700); }
.cookie-banner .btn-row .btn { flex: 1 1 140px; font-size: 0.95rem; padding: 0.7em 1em; }

/* On a phone this used to fill better than half the screen and bury the
   "Get a free quote" button underneath it on every first visit. It still says
   everything it has to say, and both choices are still equally easy to reach —
   it just stops eating the page while it does it. */
@media (max-width: 560px) {
  .cookie-banner { padding: var(--sp-4); left: var(--sp-3); right: var(--sp-3); }
  .cookie-banner h2 { font-size: 1.05rem; }
  .cookie-banner p { font-size: 0.86rem; margin-bottom: var(--sp-3); }
  .cookie-banner .btn-row { gap: var(--sp-2); }
  .cookie-banner .btn-row .btn { flex: 1 1 100%; font-size: 0.92rem; padding: 0.65em 1em; }
}

/* --------------------------------------------------------------------------
   19. Scroll reveal
   -------------------------------------------------------------------------- */
.reveal { opacity: 0; transform: translateY(18px); }
.js .reveal { transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal.is-visible { opacity: 1; transform: none; }
html:not(.js) .reveal { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal { opacity: 1 !important; transform: none !important; }
  .btn:hover, .card:hover, .photo:hover { transform: none; }
}

/* --------------------------------------------------------------------------
   20. Utilities
   -------------------------------------------------------------------------- */
.text-centre { text-align: center; }
.mb-0 { margin-bottom: 0; }
.mt-5 { margin-top: var(--sp-5); }
.mt-6 { margin-top: var(--sp-6); }
.stack-5 > * + * { margin-top: var(--sp-5); }
.split {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  align-items: center;
}
.split--top { align-items: start; }

@media print {
  .site-header, .callbar, .cookie-banner, .site-footer, .lightbox { display: none !important; }
  body { padding-bottom: 0; background: #fff; }
}
