/*
 * GENERATED FILE — do not edit. php bin/build-tokens.php
 *
 * A concatenation of tokens.css, base.css, layout.css, components.css, in that order.
 * Edit those; this is the bundle the pages actually link.
 */

/* === tokens.css ================================================== */
/*
 * GENERATED FILE — do not edit.
 *
 * php bin/build-tokens.php
 *
 * Every value here comes from data/design-profile.json, which was extracted
 * from https://dpf-fixer.co.uk/.
 *
 * No colour, size, radius or font may be hardcoded in any other stylesheet.
 * A hardcoded value does not change when the profile changes, and that is how
 * two sites built from this plan drift back into looking like siblings.
 */

:root {
  /* colour */
  --mdc-colour-primary: #1c4e80;
  --mdc-colour-secondary: #f5f7fa;
  --mdc-colour-accent: #e8a33d;
  --mdc-colour-background: #ffffff;
  --mdc-colour-surface: #f5f7fa;
  --mdc-colour-surface-dark: #132f4c;
  --mdc-colour-text: #17202e;
  --mdc-colour-text-muted: #5b6675;
  --mdc-colour-text-on-dark: #ffffff;
  --mdc-colour-border: #d7dde5;
  --mdc-colour-border-strong: #6f7b8d;
  --mdc-colour-success: #1f7a3d;

  /* type scale, 17px base at a ratio of 1.24 */
  --mdc-font-body: Helvetica Neue, Helvetica, Arial, sans-serif;
  --mdc-font-heading: Helvetica Neue, Helvetica, Arial, sans-serif;
  --mdc-weight-body: 400;
  --mdc-weight-heading: 500;
  --mdc-line-height: 1.55;
  --mdc-heading-case: none;
  --mdc-text-sm: 0.8569rem;
  --mdc-text-0: 1.0625rem;
  --mdc-text-1: 1.3175rem;
  --mdc-text-2: 1.6338rem;
  --mdc-text-3: 2.0256rem;
  --mdc-text-4: 2.5119rem;
  --mdc-text-5: 3.115rem;

  /* layout */
  --mdc-container: 1140px;
  --mdc-measure: 655px; /* 70ch of 17px body copy, at 0.55em per character */
  --mdc-gutter: 20px;
  --mdc-section-padding: 72px;
  --mdc-radius: 3px;
  --mdc-radius-pill: 40px;
  --mdc-border: 1px solid var(--mdc-colour-border);
  --mdc-shadow: none;

  /* spacing scale */
  --mdc-space-1: 4px;
  --mdc-space-2: 8px;
  --mdc-space-3: 12px;
  --mdc-space-4: 16px;
  --mdc-space-5: 20px;
  --mdc-space-6: 24px;
  --mdc-space-8: 32px;
  --mdc-space-12: 48px;

  /* breakpoints, recorded for reference; media queries cannot use variables */
  /* 480px, 768px, 1024px, 1200px */
}

/*
 * Contrast constraints, measured by bin/build-tokens.php.
 * These are not decoration: a pairing listed as failing must not be used for
 * text, whatever it looks like on the designer's monitor.
 *
 *   text on background               16.37:1  pass
 *   text on surface                  15.26:1  pass
 *   muted text on background          5.83:1  pass
 *   muted text on surface             5.43:1  pass
 *   primary as text on background     8.57:1  pass
 *   white on primary                  8.57:1  pass
 *   white on surface_dark            13.65:1  pass
 *   text on accent                    7.59:1  pass
 *   white on success                  5.37:1  pass
 *   white on accent                   2.16:1  NEVER FOR TEXT
 *   accent as text on background      2.16:1  NEVER FOR TEXT
 *   focus ring on background          8.57:1  pass
 *   strong border on background       4.29:1  pass
 *   hairline border on background     1.37:1  NEVER FOR TEXT
 */

/* === base.css ==================================================== */
/*
 * Reset, typography and element defaults.
 *
 * Every value comes from tokens.css. Nothing here is a literal colour or size,
 * except structural zeroes and the odd 100%.
 */

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

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

body {
  margin: 0;
  background: var(--mdc-colour-background);
  color: var(--mdc-colour-text);
  font-family: var(--mdc-font-body);
  font-size: var(--mdc-text-0);
  font-weight: var(--mdc-weight-body);
  line-height: var(--mdc-line-height);
}

h1, h2, h3, h4 {
  margin: 0 0 var(--mdc-space-4);
  font-family: var(--mdc-font-heading);
  font-weight: var(--mdc-weight-heading);
  text-transform: var(--mdc-heading-case);
  line-height: 1.18;
  text-wrap: balance;
}

/*
 * The reference sets headings at weight 500 rather than 700, which is a
 * noticeably lighter heading voice. Size carries the hierarchy instead.
 */
h1 { font-size: var(--mdc-text-4); }
h2 { font-size: var(--mdc-text-3); }
h3 { font-size: var(--mdc-text-2); }
h4 { font-size: var(--mdc-text-1); }

p, ul, ol, dl, blockquote, figure, table {
  margin: 0 0 var(--mdc-space-5);
}

/*
 * Line length is capped for readability; the container alone is far too wide.
 * Rendered lines were 133 characters, against a typographic norm of 45-75.
 *
 * THE MEASURE IS CENTRED, AND SO ARE THE HEADINGS ABOVE IT. Capping the
 * paragraphs alone was tried first and abandoned, because a narrow column of
 * text sitting under a full-width heading leaves an obviously empty right-hand
 * half and reads as a mistake. Measuring the whole prose column — headings
 * included — and centring it is what makes it look deliberate.
 *
 * That only works because --mdc-measure is now a fixed length. It was `70ch`,
 * which resolves against EACH ELEMENT'S OWN font size: headings got a 1261px
 * column, paragraphs a 662px one, and centring two different widths put the
 * headings 240px to the left of their own body text. See bin/build-tokens.php.
 *
 * Anything that is genuinely wide opts out with `max-width: none`: the town
 * lists, the county lists, the nav, the footer, the split hero.
 *
 * ANYTHING LAID OUT BY GRID OR FLEX MUST ALSO OPT OUT OF `margin-inline`, not
 * just the width. Auto inline margins on a grid item absorb the free space and
 * shrink the item to its content — which is what collapsed the enquiry form's
 * fields to half a column each. `max-width: none` alone does not undo it.
 */
:where(.mdc-section) :is(h2, h3, h4, p, ul, ol, dl, blockquote, figure) {
  max-width: var(--mdc-measure);
  margin-inline: auto;
}

p, li, dd, blockquote p { max-width: var(--mdc-measure); }

/* A list's items are already inside the measured list. */
:where(.mdc-section) :is(ul, ol, dl) li,
:where(.mdc-section) :is(ul, ol, dl) dd { max-width: none; }

a {
  color: var(--mdc-colour-primary);
  text-underline-offset: 0.15em;
}

a:hover { text-decoration: none; }

/*
 * A visible focus ring on every interactive element. The default outline
 * disappears against the navy, so it is set explicitly.
 */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--mdc-colour-primary);
  outline-offset: 2px;
  border-radius: var(--mdc-radius);
}

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

/*
 * CONTENT IMAGES FILL THEIR COLUMN, AND THE COLUMN IS NEVER THE PAGE.
 *
 * The images are 800x600, and `width: 100%` on its own would stretch one to
 * whatever it sits in — which on a 1140px container is a full-bleed banner
 * nobody asked for and an 800px file upscaled to 1140. So the width comes from
 * the column, and the column is capped at the reading measure and centred, the
 * same column the prose sits in.
 *
 * Below the first breakpoint the column IS the page, so the image goes edge to
 * edge on a phone. That is the one place full width is right.
 *
 * The hero is excluded: it is one half of a two-column split by design
 * (components.hero in the design profile), so it is already in a column and
 * capping it again would shrink it against the text beside it.
 */
.mdc-section img {
  width: 100%;
  max-width: var(--mdc-measure);
  margin-inline: auto;
}

.mdc-hero img,
.mdc-split__media img {
  width: 100%;
  max-width: none;
}

hr {
  border: 0;
  border-top: var(--mdc-border);
  margin: var(--mdc-space-8) 0;
}

blockquote {
  margin-left: 0;
  padding-left: var(--mdc-space-5);
  border-left: 3px solid var(--mdc-colour-accent);
}

ul, ol { padding-left: var(--mdc-space-6); }

li { margin-bottom: var(--mdc-space-2); }

dt { font-weight: var(--mdc-weight-heading); }
dd { margin: 0 0 var(--mdc-space-5); }

table {
  width: 100%;
  border-collapse: collapse;
}

th, td {
  text-align: left;
  padding: var(--mdc-space-3);
  border-bottom: var(--mdc-border);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* === layout.css ================================================== */
/*
 * Page scaffolding: the container, the section rhythm, and the two-column split.
 *
 * Class names follow the profile's convention, which is `prefixed` with the
 * prefix `mdc-`. Not BEM, not utilities, not a default house style.
 *
 * Breakpoints are 480 / 768 / 1024 / 1200. Media queries cannot read custom
 * properties, so those numbers are written out here and recorded in tokens.css
 * as a comment.
 */

.mdc-container {
  width: 100%;
  max-width: var(--mdc-container);
  margin-inline: auto;
  padding-inline: var(--mdc-gutter);
}

.mdc-page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.mdc-main { flex: 1 0 auto; }

.mdc-main > * + * { margin-top: var(--mdc-section-padding); }

.mdc-section {
  padding-block: var(--mdc-section-padding);
}

.mdc-section--tinted {
  background: var(--mdc-colour-surface);
  border-block: var(--mdc-border);
}

.mdc-section--dark {
  background: var(--mdc-colour-surface-dark);
  color: var(--mdc-colour-text-on-dark);
}

.mdc-section--dark a { color: var(--mdc-colour-text-on-dark); }

/*
 * The split. The reference puts text on the left and lets a photograph bleed
 * off the right edge, so that is what this does — reversing it would be a
 * different site.
 */
.mdc-split {
  display: grid;
  gap: var(--mdc-gutter);
}

.mdc-split__body { min-width: 0; }

.mdc-split__media { min-width: 0; }

.mdc-split__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mdc-stack > * + * { margin-top: var(--mdc-space-5); }

.mdc-grid {
  display: grid;
  gap: var(--mdc-gutter);
  grid-template-columns: 1fr;
}

.mdc-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--mdc-colour-surface-dark);
  color: var(--mdc-colour-text-on-dark);
  padding: var(--mdc-space-3) var(--mdc-space-5);
  z-index: 10;
}

.mdc-skip:focus { left: var(--mdc-space-2); }

@media (min-width: 768px) {
  .mdc-grid--2 { grid-template-columns: repeat(2, 1fr); }
  .mdc-grid--3 { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 1024px) {
  /*
   * 7/5 rather than 6/6: the copy column carries the h1, the answer paragraph
   * and the call to action, and an even split leaves it cramped.
   */
  .mdc-split {
    grid-template-columns: 7fr 5fr;
    align-items: center;
    gap: calc(var(--mdc-gutter) * 2);
  }

  .mdc-grid--4 { grid-template-columns: repeat(4, 1fr); }
}

/* === components.css ============================================== */
/*
 * The component library.
 *
 * Every pattern the layouts need, built against tokens.css. Component choices
 * come from data/design-profile.json `components`, not from taste:
 *
 *   hero            split-text-left-image-right
 *   cta             phone-pill-button
 *   service_display stacked-sections-with-tab-strip
 *   price_display   hidden-behind-cta
 *   testimonials    single-quote-block
 *   faq             headed-sections
 *   coverage        text-plus-place-list
 *   nav             inline-links-with-phone-button
 *
 * Contrast constraints from tokens.css are load-bearing here. The accent is
 * 2.16:1 against white, so it is used as a fill behind dark text, as a rule and
 * as an icon — never as a text colour and never with white on it.
 */

/* ------------------------------------------------------------------ header -- */

.mdc-header {
  border-bottom: var(--mdc-border);
  background: var(--mdc-colour-background);
}

.mdc-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--mdc-space-4) var(--mdc-space-6);
  padding-block: var(--mdc-space-4);
}

.mdc-brand {
  margin: 0;
  flex: 0 0 auto;
  font-family: var(--mdc-font-heading);
  font-size: var(--mdc-text-1);
  font-weight: var(--mdc-weight-heading);
}

.mdc-brand a {
  color: var(--mdc-colour-text);
  text-decoration: none;
  display: inline-block;
  min-height: 24px;
}

/*
 * The nav is its own full-width row under the brand and phone. Four service
 * names measure about 800px, which does not fit beside them in a 1140px
 * container, and a nav that wraps by accident reads as a mistake.
 *
 * This row is also how the profile's `stacked-sections-with-tab-strip` service
 * display is realised: a tinted strip of service links with an accent underline
 * on the current one. A second strip below it was tried and removed — it
 * repeated these links exactly, and duplicate internal links help nobody.
 */
.mdc-nav {
  border-top: var(--mdc-border);
  background: var(--mdc-colour-surface);
}

.mdc-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--mdc-space-2) var(--mdc-space-6);
  list-style: none;

  /* Block only. The ul also carries .mdc-container, and `margin: 0` here beat
     it on specificity and killed the `margin-inline: auto` that centres it —
     so the nav ran the full width of the window while the brand and the phone
     button above it sat inside the container. */
  margin-block: 0;
  padding-block: var(--mdc-space-2);
}

.mdc-nav li { margin: 0; max-width: none; }

.mdc-nav a {
  display: inline-block;
  color: var(--mdc-colour-text);
  text-decoration: none;
  padding-block: var(--mdc-space-2);
  border-bottom: 3px solid transparent;
}

.mdc-nav a:hover,
.mdc-nav a[aria-current="page"] {
  border-bottom-color: var(--mdc-colour-accent);
}

/* The mobile toggle only exists once JS has confirmed it works. */
.mdc-nav__toggle {
  display: none;
  font: inherit;
  background: var(--mdc-colour-background);
  color: var(--mdc-colour-text);
  border: 1px solid var(--mdc-colour-border-strong);
  border-radius: var(--mdc-radius);
  padding: var(--mdc-space-2) var(--mdc-space-4);
  cursor: pointer;
}

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

.mdc-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--mdc-space-2);
  padding: var(--mdc-space-3) var(--mdc-space-6);
  border: 1px solid transparent;
  border-radius: var(--mdc-radius-pill);
  font-weight: var(--mdc-weight-heading);
  text-decoration: none;
  cursor: pointer;
}

.mdc-btn--call {
  background: var(--mdc-colour-primary);
  color: var(--mdc-colour-text-on-dark);
}

.mdc-btn--call:hover { background: var(--mdc-colour-surface-dark); }

/* Dark text on the accent is 7.59:1. White on it would be 2.16:1. */
.mdc-btn--accent {
  background: var(--mdc-colour-accent);
  color: var(--mdc-colour-text);
}

.mdc-btn--ghost {
  background: transparent;
  color: var(--mdc-colour-primary);
  border-color: var(--mdc-colour-border-strong);
}

.mdc-section--dark .mdc-btn--call {
  background: var(--mdc-colour-accent);
  color: var(--mdc-colour-text);
}

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

.mdc-hero {
  background: var(--mdc-colour-surface-dark);
  color: var(--mdc-colour-text-on-dark);
}

.mdc-hero__inner { padding-block: var(--mdc-section-padding); }

.mdc-hero h1 {
  font-size: var(--mdc-text-4);
  margin-bottom: var(--mdc-space-4);
}

.mdc-hero__eyebrow {
  margin: 0 0 var(--mdc-space-2);
  color: var(--mdc-colour-accent);
  font-size: var(--mdc-text-sm);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.mdc-hero__lead {
  font-size: var(--mdc-text-1);
  color: var(--mdc-colour-text-on-dark);
  max-width: var(--mdc-measure);
}

.mdc-hero__media img { border-radius: var(--mdc-radius); }

/* ------------------------------------------------------------- the answer -- */
/*
 * The paragraph that leads every page and that AI search extracts. It is set
 * apart with a rule rather than a tinted box, matching the reference's habit of
 * separating with lines rather than filled panels.
 */

.mdc-answer {
  font-size: var(--mdc-text-1);
  border-left: 4px solid var(--mdc-colour-accent);
  padding-left: var(--mdc-space-5);
  margin-bottom: var(--mdc-space-6);
}

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

.mdc-steps ol {
  list-style: none;
  padding: 0;
  counter-reset: mdc-step;
}

.mdc-steps li {
  counter-increment: mdc-step;
  position: relative;
  padding-left: calc(var(--mdc-space-8) + var(--mdc-space-2));
  margin-bottom: var(--mdc-space-5);
  min-height: var(--mdc-space-8);
}

.mdc-steps li::before {
  content: counter(mdc-step);
  position: absolute;
  left: 0;
  top: 0;
  width: var(--mdc-space-8);
  height: var(--mdc-space-8);
  border-radius: var(--mdc-radius-pill);
  background: var(--mdc-colour-primary);
  color: var(--mdc-colour-text-on-dark);
  display: grid;
  place-items: center;
  font-weight: var(--mdc-weight-heading);
}

/* --------------------------------------------------------------- coverage -- */

.mdc-placelist {
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--mdc-space-2);
}

.mdc-placelist li {
  margin: 0;
  max-width: none;
  padding: var(--mdc-space-1) var(--mdc-space-3);
  border: var(--mdc-border);
  border-radius: var(--mdc-radius);
  background: var(--mdc-colour-surface);
  font-size: var(--mdc-text-sm);
}

/* -------------------------------------------------------------------- faq -- */
/*
 * Questions are headings inside a plain section, matching the reference. They
 * are readable with JavaScript disabled because there is no JavaScript involved:
 * <details> is open by default and only collapses if the script runs.
 */

/*
 * The accordion is a PANEL, not a hairline.
 *
 * A top border and some padding is technically an accordion and reads as a
 * stack of undifferentiated text — which is what made the page look like one
 * long column. Giving each question a surface, a border and real padding is
 * what turns the FAQ into a component you can see.
 */
.mdc-faq__item {
  background: var(--mdc-colour-surface);
  border: var(--mdc-border);
  border-radius: var(--mdc-radius);
  padding: var(--mdc-space-4) var(--mdc-space-5);
  margin-bottom: var(--mdc-space-3);
  transition: border-color .15s ease;
}

.mdc-faq__item:hover { border-color: var(--mdc-colour-border-strong); }

.mdc-faq__item[open] {
  background: var(--mdc-colour-background);
  border-color: var(--mdc-colour-border-strong);
}

.mdc-faq__item > summary {
  font-family: var(--mdc-font-heading);
  font-size: var(--mdc-text-1);
  font-weight: var(--mdc-weight-heading);
  cursor: pointer;
  list-style: none;
}

.mdc-faq__item > summary::-webkit-details-marker { display: none; }

.mdc-faq__item > summary::after {
  content: "\002B";
  float: right;
  color: var(--mdc-colour-primary);
}

.mdc-faq__item[open] > summary::after { content: "\2212"; }

.mdc-faq__item > summary + * {
  margin-top: var(--mdc-space-4);
  padding-top: var(--mdc-space-4);
  border-top: var(--mdc-border);
}

/* ------------------------------------------------------------------ lists -- */
/*
 * `.mdc-points` was used in the markup and had NO styles at all, so every
 * bullet on the site was a browser-default disc sitting hard against the text.
 * A marker in the brand colour and room between items is most of the
 * difference between a styled page and an unstyled one.
 */
.mdc-points {
  list-style: none;
  padding: 0;
}

.mdc-points > li {
  position: relative;
  padding-left: var(--mdc-space-5);
  margin-bottom: var(--mdc-space-3);
}

.mdc-points > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .62em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--mdc-colour-accent);
}

/* A tinted band already supplies the contrast, so the marker switches to the
   primary colour where the accent would fight the background. */
.mdc-section--tinted .mdc-points > li::before { background: var(--mdc-colour-primary); }

.mdc-stack { list-style: none; padding: 0; }

.mdc-stack > li {
  padding-left: var(--mdc-space-5);
  position: relative;
}

.mdc-stack > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .62em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--mdc-colour-accent);
}

/* ------------------------------------------------------------------ about -- */
/*
 * The only genuinely per-location prose on the page, written in a different
 * voice from the rest. It is visibly delimited so the change of voice reads as
 * deliberate rather than as a seam.
 */

.mdc-about {
  background: var(--mdc-colour-surface);
  border: var(--mdc-border);
  border-radius: var(--mdc-radius);
  padding: var(--mdc-space-6);
}

.mdc-about h2 { font-size: var(--mdc-text-1); }

.mdc-about p:last-child { margin-bottom: 0; }

/* ----------------------------------------------------------------- review -- */

/*
 * A CARD, not a pair of rules.
 *
 * Horizontal rules above and below a quote separate it from the text without
 * ever making it look like an object, so three of them in a row read as more
 * body copy with lines through it. A surface, a border and padding is what
 * makes a review look like a review at a glance.
 */
.mdc-review {
  margin: var(--mdc-space-6) 0;
  padding: var(--mdc-space-5);
  background: var(--mdc-colour-background);
  border: var(--mdc-border);
  border-radius: var(--mdc-radius);
  display: flex;
  flex-direction: column;
}

/* On a tinted band the card needs to lift off the background, not sink into it. */
.mdc-section--tinted .mdc-review { background: var(--mdc-colour-background); }

/*
 * The accent rule moves off the quote and becomes a short mark above it. Inside
 * a bordered card a left rule fights the card's own border; a mark reads as a
 * deliberate flourish rather than a second edge.
 */
.mdc-review blockquote {
  margin: 0 0 var(--mdc-space-4);
  border-left: 0;
  padding: 0;
  flex: 1;
}

.mdc-review blockquote::before {
  content: "";
  display: block;
  width: 32px;
  height: 3px;
  background: var(--mdc-colour-accent);
  margin-bottom: var(--mdc-space-4);
}

.mdc-review blockquote p { max-width: none; margin: 0; }

.mdc-review figcaption {
  color: var(--mdc-colour-text-muted);
  font-size: var(--mdc-text-sm);
  border-top: var(--mdc-border);
  padding-top: var(--mdc-space-3);
  margin-top: auto;
}

/* -------------------------------------------------------------------- cta -- */

/*
 * THE CTA IS A BAND ACROSS THE PAGE, NOT A CARD INSIDE IT.
 *
 * `.mdc-cta` on its own is a dark rounded box, and because it sits inside the
 * 1140px container it rendered as a dark rectangle with white either side —
 * which reads as a component that has come loose rather than as a change of
 * gear in the page.
 *
 * `.mdc-section--cta` puts the colour on the SECTION, which is outside the
 * container and therefore spans the viewport. The card inside then stops being
 * a card: no background of its own, no radius, no padding, because the band is
 * already providing all three.
 */
.mdc-section--cta {
  background: var(--mdc-colour-surface-dark);
  color: var(--mdc-colour-text-on-dark);
}

.mdc-section--cta :is(h2, h3, p, li, dt, dd) { color: var(--mdc-colour-text-on-dark); }

.mdc-section--cta .mdc-cta {
  background: none;
  border-radius: 0;
  padding: 0;
}

.mdc-cta {
  background: var(--mdc-colour-surface-dark);
  color: var(--mdc-colour-text-on-dark);
  border-radius: var(--mdc-radius);
  padding: var(--mdc-space-8);
}

.mdc-cta h2 { margin-top: 0; }

.mdc-cta p { max-width: none; }

.mdc-cta a { color: var(--mdc-colour-text-on-dark); }

/*
 * ...except a button, which brings its own background and therefore its own
 * contrast. The rule above is right for links on the dark card and wrong for
 * the call button sitting on the accent: white on #e8a33d fails AA, which the
 * colour tests already say in as many words. Inheriting text-on-dark into a
 * button is the sort of thing that looks fine and measures 2.1:1.
 */
.mdc-cta a.mdc-btn--accent { color: var(--mdc-colour-text); }

.mdc-cta a.mdc-btn--ghost { color: var(--mdc-colour-text-on-dark); }

/* ------------------------------------------------------------- sticky bar -- */

/*
 * Phone only. Above this width the header's own call button never leaves the
 * screen, so a second fixed one would just cover the page.
 */
.mdc-stickybar { display: none; }

@media (max-width: 767px) {
  .mdc-stickybar {
    display: flex;
    position: fixed;
    inset: auto 0 0 0;
    z-index: 20;
    border-top: 1px solid var(--mdc-colour-border-strong);
    background: var(--mdc-colour-surface-dark);
  }

  .mdc-stickybar__btn {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--mdc-space-2);

    /* A tap target, and clear of the home indicator on a modern phone. */
    min-height: 56px;
    padding: var(--mdc-space-3) var(--mdc-space-2);
    padding-bottom: max(var(--mdc-space-3), env(safe-area-inset-bottom));

    color: var(--mdc-colour-text-on-dark);
    font-weight: var(--mdc-weight-heading);
    text-decoration: none;
  }

  .mdc-stickybar__btn + .mdc-stickybar__btn {
    border-left: 1px solid var(--mdc-colour-border-strong);
  }

  .mdc-stickybar__btn--alt {
    background: var(--mdc-colour-accent);
    color: var(--mdc-colour-text);
  }

  /* The bar covers the foot of the page otherwise, and the last thing on these
     pages is the review attribution and the accreditations. */
  .mdc-page { padding-bottom: 64px; }

  /* Jumping to the form must not land it under the sticky header area. */
  #enquiry { scroll-margin-top: var(--mdc-space-5); }
}

/* ---------------------------------------------------------------- reviews -- */

.mdc-reviews__grid {
  display: grid;
  gap: var(--mdc-gutter);
  grid-template-columns: 1fr;
}

/* Three across once there is room; stacked below that, which is the phone. */
@media (min-width: 768px) {
  .mdc-reviews__grid { grid-template-columns: repeat(3, 1fr); }
}

.mdc-reviews__grid .mdc-review {
  margin: 0;
  height: 100%;
}

.mdc-reviews__link {
  margin-top: var(--mdc-space-5);
  max-width: none;
}

/* ----------------------------------------------------------------- triage -- */

/*
 * Template 3 puts its answer above the explanation, so the answer needs to look
 * like the thing to read first. A bordered panel rather than a tinted band,
 * because the tinted bands are already doing the alternating-rhythm job further
 * down the page.
 */

.mdc-triage {
  border: var(--mdc-border);
  border-left: 4px solid var(--mdc-colour-primary);
  border-radius: var(--mdc-radius);
  padding: var(--mdc-space-6);
  background: var(--mdc-colour-surface);
}

.mdc-triage h2 { margin-top: 0; }

.mdc-triage ul { margin-bottom: 0; }

/* -------------------------------------------------------------- faq as a dl -- */

/*
 * The third FAQ treatment on this site: template 1 uses <details>, template 2
 * headings and paragraphs, this one a definition list. All three read with
 * JavaScript off; only this one says "question and answer" in the markup.
 */

.mdc-faq dt {
  font-weight: var(--mdc-weight-heading);
  font-size: var(--mdc-text-2);
  margin-top: var(--mdc-space-5);
}

.mdc-faq dd {
  margin: var(--mdc-space-2) 0 0;
  max-width: var(--mdc-measure);
}

/* ------------------------------------------------------------ enquiry form -- */

/*
 * The form sits inside .mdc-cta, which is already the dark closing card, so the
 * form itself is a light panel on top of it. Every colour is a token: the
 * reference this was matched against is green, and the palette in
 * data/design-profile.json is not, so taking its colours would have put a
 * second, unrelated scheme on the page.
 */

.mdc-contact__actions {
  margin-block: var(--mdc-space-5);
  max-width: none;
}

/* The trust line and the attribution follow the form, so they need to clear it
   rather than butt against the card's bottom edge. */
.mdc-cta .mdc-form + p {
  margin-top: var(--mdc-space-6);
}

.mdc-form {
  background: var(--mdc-colour-background);
  color: var(--mdc-colour-text);
  border-radius: var(--mdc-radius);
  padding: var(--mdc-space-6);

  /* Full width of the card, not a 34rem column stranded on the left with the
     dark panel showing down one side of it. */
  max-width: none;
  margin-block: var(--mdc-space-6);
}

.mdc-form__title {
  margin-top: 0;
  margin-bottom: var(--mdc-space-5);
  font-size: var(--mdc-text-2);

  /* Grid item: auto inline margins would shrink it to its own text. */
  margin-inline: 0;

  /* It is a short line. Let it be one where there is room, instead of
     wrapping mid-sentence at a width the heading never needed. */
  max-width: none;
  text-wrap: balance;
}

/* Two columns for the short fields once there is room; the textarea and the
   button always span. A phone gets one column, which is what the fields want. */
@media (min-width: 640px) {
  .mdc-form {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 var(--mdc-gutter);
  }

  .mdc-form__title,
  .mdc-form > .mdc-field:has(textarea),
  .mdc-form > .mdc-btn,
  .mdc-form__hp {
    grid-column: 1 / -1;
  }
}

/*
 * THE FORM IS A WHITE CARD INSIDE A DARK BAND, SO ITS TEXT STAYS DARK.
 *
 * `.mdc-section--cta` sets light text on the band and repeats it on the
 * elements inside, because inheritance alone does not reach elements that have
 * their own colour. That rule matched the form's own `h3.mdc-form__title` and
 * every `p.mdc-field` wrapper — so the title and all six labels rendered white
 * on white and simply were not there. Only the muted "(optional)" span, which
 * has a colour of its own, stayed visible.
 *
 * Two class names deep, so this outranks the band rule. The span keeps its own
 * muted colour: it is not listed here.
 */
.mdc-cta .mdc-form,
.mdc-cta .mdc-form a,
.mdc-section--cta .mdc-form,
.mdc-section--cta .mdc-form :is(h2, h3, p, li, dt, dd, label) {
  color: var(--mdc-colour-text);
}

/*
 * A field fills its grid column. Both declarations are load-bearing.
 *
 * `max-width: none` undoes the prose measure. `margin-inline: 0` undoes the
 * centring that comes with it — and that is the one that actually mattered: on
 * a grid item, auto inline margins eat the free space and the item collapses to
 * its content width, so every field rendered at roughly half its column and
 * floated in the middle of it. It looked like the widths had been set at
 * random. They had never been set at all.
 */
.mdc-field {
  display: flex;
  flex-direction: column;
  gap: var(--mdc-space-1);
  margin-block: var(--mdc-space-4);
  max-width: none;
  margin-inline: 0;
}


.mdc-field label {
  font-size: var(--mdc-text-sm);
  font-weight: var(--mdc-weight-heading);
}

.mdc-field label span {
  font-weight: var(--mdc-weight-body);
  color: var(--mdc-colour-text-muted);
}

.mdc-field input,
.mdc-field textarea {
  font: inherit;
  color: inherit;
  background: var(--mdc-colour-background);
  border: var(--mdc-border);
  border-radius: var(--mdc-radius);
  padding: var(--mdc-space-2) var(--mdc-space-3);
  width: 100%;
}

.mdc-field textarea {
  resize: vertical;
  min-height: 6rem;
}

.mdc-field input:focus-visible,
.mdc-field textarea:focus-visible {
  outline: 2px solid var(--mdc-colour-primary);
  outline-offset: 1px;
}

/*
 * The honeypot. Taken out of the layout and off the accessibility tree rather
 * than display:none — some bots skip what is display:none, which is the one
 * thing this field must not be skipped by.
 */
.mdc-form__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---------------------------------------------------------------- gallery -- */

.mdc-gallery {
  display: grid;
  gap: var(--mdc-space-3);
  grid-template-columns: repeat(2, 1fr);
}

@media (min-width: 768px) {
  .mdc-gallery { grid-template-columns: repeat(4, 1fr); }
}

.mdc-gallery img { border-radius: var(--mdc-radius); }

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

.mdc-footer {
  margin-top: var(--mdc-section-padding);
  background: var(--mdc-colour-surface-dark);
  color: var(--mdc-colour-text-on-dark);
  padding-block: var(--mdc-section-padding);
}

/*
 * WCAG 2.2 asks for a 24x24 target unless the link sits inline in a sentence.
 * These are standalone links in lists, so they are padded to clear it — at the
 * default line height they would be 19px.
 */
.mdc-footer a {
  color: var(--mdc-colour-text-on-dark);
  display: inline-block;
  padding-block: var(--mdc-space-1);
  min-height: 24px;
}

.mdc-footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--mdc-space-2) var(--mdc-space-5);
  list-style: none;
  padding: 0;
}

.mdc-footer-nav li { margin: 0; max-width: none; }

/* ----------------------------------------------------------------- notice -- */

/* The measure cap in base.css is for body copy; a full-width band opts out. */
.mdc-notice {
  max-width: none;
  background: var(--mdc-colour-accent);
  color: var(--mdc-colour-text);
  padding: var(--mdc-space-3) var(--mdc-space-5);
  margin: 0;
  font-size: var(--mdc-text-sm);
  text-align: center;
}

/* ------------------------------------------------------------------ lists -- */

.mdc-location-list,
.mdc-service-list,
.mdc-county-list {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--mdc-space-2);
  grid-template-columns: 1fr;
}

@media (min-width: 480px) {
  .mdc-location-list,
  .mdc-county-list { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 768px) {
  .mdc-location-list,
  .mdc-county-list { grid-template-columns: repeat(3, 1fr); }
}

.mdc-location-list li,
.mdc-service-list li,
.mdc-county-list li { margin: 0; max-width: none; }

.mdc-location-list a,
.mdc-service-list a,
.mdc-county-list a {
  display: inline-block;
  padding-block: var(--mdc-space-1);
  min-height: 24px;
}

/* --------------------------------------------------------------- coverage -- */

/*
 * The county page's town list. Up to 1,000 entries, so it is denser than the
 * other lists on the site and runs to more columns: this is an index to be
 * scanned for a place name, not a set of links to be read one at a time.
 */
.mdc-coverage-list {
  list-style: none;
  padding: 0;
  margin-block: var(--mdc-space-4);
  max-width: none;
  display: grid;
  gap: 0 var(--mdc-space-4);
  grid-template-columns: 1fr;
}

@media (min-width: 480px) { .mdc-coverage-list { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 768px) { .mdc-coverage-list { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .mdc-coverage-list { grid-template-columns: repeat(4, 1fr); } }

.mdc-coverage-list li { margin: 0; max-width: none; }

/* 24px of height on every row: a thousand links at the default line height are
   a thousand tap targets too close together to hit on a phone. */
.mdc-coverage-list a {
  display: block;
  padding-block: var(--mdc-space-1);
  min-height: 24px;
  font-size: var(--mdc-text-sm);
}

/* The count beside each county name on a hub. Secondary to the link, never
   competing with it. */
.mdc-county-list__count {
  color: var(--mdc-colour-text-muted);
  font-size: var(--mdc-text-sm);
}

/* The links up and out of a location page: to its county, and to its own hub. */
.mdc-area-nav {
  margin-block: var(--mdc-space-5);
  border-top: var(--mdc-border);
  padding-top: var(--mdc-space-3);
}

.mdc-area-nav ul {
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--mdc-space-2) var(--mdc-space-5);
}

.mdc-area-nav li { margin: 0; max-width: none; }

/* ------------------------------------------------------- mobile behaviour -- */

@media (max-width: 767px) {
  .mdc-nav__toggle { display: block; margin: var(--mdc-space-3) var(--mdc-gutter); }

  .mdc-nav[data-collapsed="true"] ul { display: none; }

  .mdc-nav ul {
    flex-direction: column;
    gap: 0;
  }

  .mdc-nav li { border-top: var(--mdc-border); }

  .mdc-nav a { display: block; padding-block: var(--mdc-space-3); }

  .mdc-header__inner { gap: var(--mdc-space-3); }

  .mdc-hero h1 { font-size: var(--mdc-text-3); }

  .mdc-cta { padding: var(--mdc-space-5); }
}
