/* ==========================================================================
   AzRated — Energy Performance Certificates & floor plans, London
   Implemented from "AzRated Website v2.dc.html" (Claude Design export).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   Colours carried over from the design. Several greys were darkened/lightened
   from the source values to clear WCAG AA (4.5:1) at the sizes they are used —
   the original picks sat between 2.7:1 and 4.2:1. Brand purple and the two
   surface colours are unchanged.
   -------------------------------------------------------------------------- */
:root {
  /* Brand */
  --purple:        #762FA3;
  --purple-dark:   #5B2280;
  --purple-wash:   #F4EEF8;
  --purple-soft:   #C7A6DC;
  --purple-onDark: #D3B8E4;  /* was #C7A6DC — 4.15:1 on --dark */

  /* Ink */
  --ink:      #2C2C2B;
  --body:     #494948;
  --muted:    #5A5A58;
  --muted-2:  #71716F;
  --muted-3:  #6F6F6D;       /* was #8C8C8A / #9A9A98 — both under 3.5:1 */
  --plan-ink: #6B5B78;       /* was #A08BB2 — 2.8:1 */
  --counter:  #7E5C99;       /* was #B79ACB — 2.2:1 */

  /* Surfaces */
  --bg:        #FEFEFE;
  --bg-tint:   #FAF7FC;
  --bg-tint-2: #FBF9FC;
  --dark:      #494948;
  --dark-2:    #5D5D5B;

  /* On dark */
  --on-dark:       #FEFEFE;
  --on-dark-body:  #C3C3C1;
  --on-dark-link:  #D6D6D4;
  --on-dark-muted: #BDBDBB;  /* was #9A9A98 / #A6A6A4 — both under 3.6:1 */

  /* Lines */
  --line:     #E9E3EE;
  --line-2:   #EEE9F1;
  --line-3:   #EDE7F0;
  --line-4:   #E6DFEB;
  --field:    #E3DCE9;
  --outline:  #DCD4E3;

  --star: #A66200;           /* was #E8A317 — 2.1:1 on white; stars are glyphs, so they need text contrast */

  /* Type */
  --display: 'Sora', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --sans:    'Manrope', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Metrics */
  --wrap:    1280px;
  --gutter:  30px;
  --header-h: 65px;
  --radius:  16px;
  --shadow:  0 14px 40px rgba(44, 44, 43, .05);
  --shadow-cta: 0 8px 22px rgba(118, 47, 163, .18);
}

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

html {
  scroll-behavior: smooth;
  /* Sticky header would otherwise cover the top of every anchor target. */
  scroll-padding-top: calc(var(--header-h) + 20px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--body);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* The browser's own `[hidden] { display: none }` is a user-agent rule, so ANY
   author rule that sets `display` beats it and the element stays on screen.
   That silently un-hid the quote form's "Request received" panel, which sets
   `display: flex`. Enforce it once, globally, so it cannot happen again. */
[hidden] { display: none !important; }

a { color: var(--purple); text-decoration: none; }
a:hover { color: var(--purple-dark); }

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

input, textarea, select, button { font: inherit; color: inherit; }

h1, h2, h3 { font-family: var(--display); letter-spacing: -.035em; color: var(--ink); }

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

.skip {
  position: absolute;
  left: 12px;
  top: -100px;
  z-index: 200;
  background: var(--purple);
  color: var(--on-dark);
  padding: 12px 20px;
  border-radius: 8px;
  font-weight: 700;
  transition: top .15s;
}
.skip:focus { top: 12px; color: var(--on-dark); }

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

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

.section { padding: clamp(64px, 7vw, 104px) var(--gutter); }
.section--flush-top { padding-top: 0; }

.section--tint {
  background: var(--bg-tint);
  border-block: 1px solid var(--line-2);
}

.section--dark {
  background: var(--dark);
  color: var(--on-dark);
}
.section--dark h2,
.section--dark h3 { color: var(--on-dark); }

.eyebrow {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--purple);
  margin-bottom: 16px;
}
.section--dark .eyebrow { color: var(--purple-onDark); }

.h2 {
  font-size: clamp(30px, 3.4vw, 42px);
  line-height: 1.1;
  font-weight: 700;
  margin: 0 0 16px;
  text-wrap: balance;
}

.lede {
  font-size: 18px;
  color: var(--muted);
  margin: 0;
  text-wrap: pretty;
}
.section--dark .lede { color: var(--on-dark-body); }

.section-head { max-width: 660px; margin-bottom: 44px; }
.section-head > .h2:last-child { margin-bottom: 0; }

.split-head {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 40px;
}

.link-arrow {
  font-weight: 700;
  font-size: 16px;
}
/* Non-breaking space keeps the arrow glued to the final word, so the label can
   wrap on narrow screens without the arrow orphaning onto its own line. The
   previous `white-space: nowrap` forced overflow below ~340px. */
.link-arrow::after { content: '\00A0\2192'; }

.grid {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}
.grid--wide  { grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr)); }
.grid--split { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: clamp(36px, 5vw, 72px); align-items: start; }

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-block;
  border: 1.5px solid transparent;
  border-radius: 9px;
  font-weight: 700;
  font-size: 16px;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  transition: background-color .15s, border-color .15s, color .15s;
}

.btn--primary {
  background: var(--purple);
  color: var(--on-dark);
  padding: 14px 26px;
}
.btn--primary:hover { background: var(--purple-dark); color: var(--on-dark); }

.btn--ghost {
  border-color: var(--outline);
  color: var(--body);
  background: var(--bg);
  padding: 13px 24px;
}
.btn--ghost:hover { border-color: var(--purple); color: var(--purple); }

.btn--lg { font-size: 17px; padding: 17px 32px; letter-spacing: -.01em; }
.btn--lg.btn--primary { box-shadow: var(--shadow-cta); }
.btn--lg.btn--ghost { padding: 16px 28px; background: rgba(254, 254, 254, .7); border-color: #D3C9DB; }

.btn--block { display: block; width: 100%; }
.btn--sm { font-size: 15.5px; padding: 13px; }

/* --------------------------------------------------------------------------
   5. Header
   -------------------------------------------------------------------------- */
.header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(254, 254, 254, .9);
  border-bottom: 1px solid var(--line-2);
}
@supports (backdrop-filter: blur(14px)) {
  .header { backdrop-filter: blur(14px); }
}

.header--scrolled {
  border-bottom-color: #E2D9E9;
  box-shadow: 0 6px 24px rgba(44, 44, 43, .06);
}

.header__inner {
  max-width: var(--wrap);
  margin-inline: auto;
  padding: 12px var(--gutter);
  display: flex;
  align-items: center;
  gap: 28px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  flex-shrink: 0;
  color: var(--ink);
}
.brand:hover { color: var(--ink); }
/* The monogram only, cropped out of the full lockup — the original tile also
   contained a miniature "AzRated" wordmark, which was both illegible at this
   size (reading as blurry) and redundant next to the live text beside it.
   Height drives the size; the mark is 641x523 so a square would distort it. */
.brand__mark {
  height: 40px;
  width: auto;
  display: block;
  flex-shrink: 0;
}
/* The lockup is two-tone: "Az" in brand purple, "Rated" in charcoal — matching
   the letter fills in the source logo (#7630A0/#7530A0 and #4A4A48/#494947,
   snapped to the exact brand hexes). Rendering the whole word in one colour
   was what made "Az" read as charcoal. */
.brand__name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -.03em;
  color: var(--body);      /* #494948 — "Rated" */
}
.brand__az { color: var(--purple); }   /* #762FA3 — "Az" */

.nav {
  display: flex;
  align-items: center;
  /* Three links rather than six, so they can breathe a little more without
     crowding the phone number and CTA on the right. */
  gap: 6px;
  margin-left: auto;
}

/* Links sit in their own optically-even group; the phone number and CTA are
   pushed off to the right behind a hairline so the bar reads in three parts. */
.nav__link {
  position: relative;
  color: #4F4F4E;
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -.005em;
  padding: 9px 15px;
  border-radius: 8px;
  white-space: nowrap;
  transition: color .15s, background-color .15s;
}
.nav__link::after {
  content: '';
  position: absolute;
  left: 15px; right: 15px; bottom: 5px;
  height: 1.5px;
  border-radius: 2px;
  background: var(--purple);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .2s ease;
}
.nav__link:hover { color: var(--purple); }
.nav__link:hover::after { transform: scaleX(1); }

/* Current page. The underline is the same one hover draws, held open, so the
   bar has a single visual language rather than two competing states. */
.nav__link[aria-current='page'] { color: var(--purple); }
.nav__link[aria-current='page']::after { transform: scaleX(1); }

.nav__sep {
  width: 1px;
  height: 22px;
  background: var(--line-2);
  margin: 0 14px 0 10px;
  flex-shrink: 0;
}

.nav__tel {
  font-family: var(--mono);
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: -.01em;
  color: #4F4F4E;
  padding: 9px 10px;
  border-radius: 8px;
  white-space: nowrap;
  transition: color .15s;
}
.nav__tel:hover { color: var(--purple); }

.nav__cta {
  background: var(--purple);
  color: var(--on-dark);
  padding: 11px 20px;
  margin-left: 10px;
  border-radius: 8px;
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: -.01em;
  white-space: nowrap;
  box-shadow: 0 4px 12px rgba(118, 47, 163, .22);
  transition: background-color .15s, box-shadow .15s, transform .15s;
}
.nav__cta:hover {
  background: var(--purple-dark);
  color: var(--on-dark);
  box-shadow: 0 6px 18px rgba(118, 47, 163, .3);
  transform: translateY(-1px);
}

/* Hamburger — only rendered/active below the desktop breakpoint. */
.nav-toggle {
  display: none;
  margin-left: auto;
  width: 44px; height: 44px;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1.5px solid var(--outline);
  border-radius: 9px;
  cursor: pointer;
}
.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: '';
  display: block;
  width: 18px; height: 2px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform .2s, opacity .2s;
}
.nav-toggle__bars { position: relative; }
.nav-toggle__bars::before { position: absolute; top: -6px; }
.nav-toggle__bars::after  { position: absolute; top: 6px; }

.nav-toggle[aria-expanded='true'] .nav-toggle__bars { background: transparent; }
.nav-toggle[aria-expanded='true'] .nav-toggle__bars::before { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded='true'] .nav-toggle__bars::after  { transform: translateY(-6px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   6. Hero
   The design referenced hero-bg.png (a white→purple wash with a fine
   blueprint grid). Rebuilt here in CSS: same gradient ramp and 48px grid
   sampled from the original, but resolution-independent and ~0 bytes.
   To go back to a bitmap, set --hero-image below to url('...').
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  overflow: hidden;
  min-height: min(84vh, 760px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(96px, 12vw, 180px) var(--gutter) clamp(30px, 3vw, 44px);
  border-bottom: 1px solid var(--line-2);
  background-color: #FCFAFD;
  /* Grid lines removed at your request — just the wash and the plan art now. */
  background-image:
    url('hero-bg.svg'),
    linear-gradient(100deg,
      #FEFEFE 0%,  #FDFDFE 14%, #F8F4F9 28%, #EFE8F2 38%,
      #E3D3EB 50%, #D4C1E2 58%, #C7ABD8 67%, #B994D0 75%,
      #B189CB 85%, #BF9FD5 100%);
  background-repeat: no-repeat, no-repeat;
  background-position: right -60px center, 0 0;
  background-size: auto 116%, cover;
}

/* Legibility scrim over the text column, as in the source design. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(96deg,
    rgba(254,254,254,.90) 0%,
    rgba(254,254,254,.62) 34%,
    rgba(254,254,254,.10) 62%,
    rgba(254,254,254,0)  100%);
}

.hero__inner { position: relative; z-index: 1; }

.hero__cols {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: clamp(28px, 4vw, 64px);
}
.hero__main { flex: 1 1 min(100%, 360px); min-width: 0; }
.hero__aside { flex: 0 1 262px; min-width: 0; }

.hero__eyebrow { margin-bottom: 22px; }

.hero h1 {
  font-size: clamp(38px, 4.8vw, 58px);
  line-height: 1.05;
  font-weight: 700;
  letter-spacing: -.04em;
  margin: 0 0 22px;
  text-wrap: balance;
}

.hero__lede {
  font-size: 19px;
  color: var(--muted);
  margin: 0 0 26px;
  max-width: 520px;
  text-wrap: pretty;
}

.stats {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 30px;
  padding: 0;
  list-style: none;
}
.stat {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  background: rgba(254, 254, 254, .82);
  border: 1px solid #E4DBEA;
  border-radius: 100px;
  padding: 8px 16px;
}
.stat b { font-family: var(--display); font-size: 15px; color: var(--purple); }
.stat span { font-size: 13.5px; color: var(--muted); }

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-bottom: 30px;
}

/* Rating badges — one per review platform, styled identically so neither
   looks more "official" than the other. */
.proof {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 30px;
  padding: 0;
  list-style: none;
}
.proof > li { display: flex; flex: 0 1 auto; min-width: 0; }
.proof > li > .proof-badge { flex: 1 1 auto; }

.proof-badge {
  display: flex;
  align-items: center;
  gap: 12px;
  background: rgba(254, 254, 254, .92);
  border: 1px solid #E4DBEA;
  border-radius: 12px;
  padding: 10px 16px 10px 12px;
  color: var(--ink);
  transition: border-color .15s, box-shadow .15s;
}
a.proof-badge:hover {
  color: var(--ink);
  border-color: var(--purple);
  box-shadow: 0 4px 14px rgba(118, 47, 163, .1);
}

.proof-badge__mark {
  width: 32px; height: 32px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1.5px solid #E1D8E8;
  background: var(--bg);
  display: grid;
  place-items: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: 15px;
  color: var(--purple);
}
.proof-badge__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.proof-badge__row { display: flex; align-items: center; gap: 7px; }
.proof-badge__score {
  font-family: var(--display);
  font-weight: 700;
  font-size: 17px;
  line-height: 1;
  color: var(--ink);
}
.proof-badge__stars { color: var(--star); font-size: 12px; letter-spacing: 1.5px; }
.proof-badge__meta { font-size: 12px; color: var(--muted-2); line-height: 1.3; }

/* --- Checkatrade widget -------------------------------------------------
   Their script renders inline at the <script> tag using plain DOM — no
   iframe, no shadow root — so it can be restyled from here. Left alone it
   paints in Checkatrade red (#FF3F3F) on navy (#040154); the rules below
   strip that back and map it onto the AzRated palette so it reads as part
   of the same set as the Google badge.

   If the widget doesn't paint (their API rejects requests without a
   Referer, so it stays blank on localhost), main.js draws .ca-fallback
   instead using the last confirmed score. ------------------------------- */
.ca-slot { font-size: 12px; line-height: 1.3; min-width: 0; }

/* Flatten the widget's own chrome */
.ca-slot,
.ca-slot * {
  font-family: var(--sans) !important;
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  margin: 0 !important;
  padding: 0 !important;
  max-width: 100%;
}
.ca-slot * { color: var(--ink) !important; }
.ca-slot a { text-decoration: none !important; }
.ca-slot a:hover * { color: var(--purple) !important; }
.ca-slot img { max-height: 26px; width: auto; }

/* Their brand colours -> ours, wherever they land */
.ca-slot [fill="#FF3F3F"], .ca-slot [stroke="#FF3F3F"] { fill: var(--purple) !important; stroke: var(--purple) !important; }
.ca-slot [fill="#040154"], .ca-slot [stroke="#040154"] { fill: var(--ink) !important; stroke: var(--ink) !important; }
.ca-slot [style*="FF3F3F"], .ca-slot [style*="ff3f3f"] { color: var(--purple) !important; }
.ca-slot [style*="040154"] { color: var(--ink) !important; }
.ca-slot svg { max-height: 26px; width: auto; }

/* Our own badge, drawn when the widget stays blank */
.ca-fallback { display: flex; flex-direction: column; gap: 2px; }
.ca-fallback .proof-badge__row { display: flex; align-items: center; gap: 7px; }

/* Single inline credential line. It's a <p> with real middots rather than a
   list with CSS-generated separators — that earlier version fell back to
   browser bullets the moment the rule went missing. */
.trust {
  margin: 0;
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.7;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--body);
  text-wrap: pretty;
}

/* Hero contact card */
.hero__aside-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--body);
  margin-bottom: 6px;
}
.hero__aside h2 {
  font-family: var(--display);
  font-weight: 700;
  font-size: 26px;
  letter-spacing: -.03em;
  margin: 0 0 18px;
}

.contact-cards { display: flex; flex-direction: column; gap: 10px; }

.contact-card {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px 18px;
  color: var(--ink);
  transition: border-color .15s;
}
.contact-card:hover { border-color: var(--purple); color: var(--ink); }

.contact-card__icon {
  width: 34px; height: 34px;
  flex-shrink: 0;
  border-radius: 9px;
  background: var(--purple-wash);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--purple);
}
.contact-card__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow-wrap: break-word;
}
.contact-card__label { font-size: 12.5px; color: var(--muted-3); font-weight: 600; }
.contact-card__value { font-size: 18px; font-weight: 700; }
.contact-card__value--sm { font-size: 14.5px; letter-spacing: -.01em; }

.hero__aside-note {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--body);
  margin: 12px 0 0;
}

/* --------------------------------------------------------------------------
   7. Sample work
   -------------------------------------------------------------------------- */
/* The card IS the mat. With the captions removed there is nothing left to wrap,
   so the border, radius and image surface live on a single element instead of
   a wrapper plus an inner media box.

   Square, not 4:3 — the real documents run 0.80 to 1.42 aspect ratio and three
   of the four are portrait, so a square mat shows them appreciably larger than
   a landscape one would, and keeps every card in the row the same height. */
.sample {
  position: relative;
  margin: 0;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Every sample is now exported onto an identical 1500x1500 white canvas with
     the artwork centred, so the card is simply the image edge-to-edge. That
     replaces the old approach — a blueprint-grid mat contain-fitting four
     different aspect ratios — which is what made the set look mismatched. */
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #FFF;
  /* It's a <button> so the thumbnails are keyboard-operable for free. */
  font: inherit;
  color: inherit;
  text-align: center;
  appearance: none;
  -webkit-appearance: none;
  cursor: zoom-in;
  transition: border-color .16s, box-shadow .16s, transform .16s;
}
.sample:hover {
  border-color: var(--purple);
  box-shadow: 0 10px 26px rgba(118, 47, 163, .14);
  transform: translateY(-2px);
}
.sample:hover img { transform: scale(1.02); }
.sample:hover .sample__zoom,
.sample:focus-visible .sample__zoom { opacity: 1; transform: none; }

/* Magnifier badge — a visible affordance that the card opens larger. */
.sample__zoom {
  position: absolute;
  right: 10px;
  bottom: 10px;
  z-index: 2;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: rgba(254, 254, 254, .94);
  border: 1px solid var(--line);
  color: var(--purple);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity .16s, transform .16s;
}
@media (hover: none) { .sample__zoom { opacity: 1; transform: none; } }

/* The placeholder sits UNDER the artwork rather than the image being hidden
   until JS reveals it. Gating `display` on a JS-added class meant the <img>
   had no layout box, which (a) can stop a loading="lazy" fetch from ever
   firing — no box, no intersection, no load event, so the class that would
   un-hide it never arrives — and (b) meant no sample image rendered at all
   with JS disabled. Now the image is visible by default and the placeholder
   is simply revealed if main.js removes a broken <img>. */
.sample__ph {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 18px;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--plan-ink);
  text-align: center;
  line-height: 1.7;
}
.sample__ph b {
  display: block;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted-2);
}

/* <picture> is only a wrapper for the WebP/JPEG choice — it must not
   introduce a box of its own. */
.sample picture { display: contents; }

/* CONTAIN, never cover. `cover` would crop the sheet to fill the square and
   take room names, dimensions and the north arrow off the edges — exactly the
   information these cards exist to show. */
/* The canvases are square and so is the card, so `contain` fills it exactly —
   identical rendered size on every card, and no cropping of room labels,
   dimensions or the north arrow. */
.sample img {
  position: relative;   /* paints over the placeholder beneath it */
  z-index: 1;
  transition: transform .16s;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  background: #FFF;
}

/* Hide the placeholder whenever an <img> is present — no JavaScript required,
   so the images still render with scripting disabled. main.js removes a broken
   <img> instead of leaving a broken-image icon, which makes :has(img) stop
   matching and brings the placeholder back. `.has-image` is the fallback for
   browsers without :has(). */
.sample:has(img) .sample__ph,
.sample.has-image .sample__ph { display: none; }

/* With no image there is nothing to enlarge, so the card stops behaving
   like a button (main.js disables it). */
.sample:not(:has(img)) { cursor: default; }
.sample:not(:has(img)):hover {
  border-color: var(--line);
  box-shadow: none;
  transform: none;
}
.sample:not(:has(img)) .sample__zoom { display: none; }

/* --------------------------------------------------------------------------
   7b. Lightbox
   -------------------------------------------------------------------------- */
.lightbox {
  width: min(96vw, 1500px);
  max-width: none;
  max-height: 94vh;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: visible;
}
.lightbox::backdrop {
  background: rgba(30, 26, 34, .86);
  backdrop-filter: blur(4px);
}

.lightbox__figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.lightbox__img {
  display: block;
  max-width: 100%;
  max-height: 84vh;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 6px;
  background: #FFF;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .5);
}
.lightbox__caption {
  margin: 0;
  max-width: 68ch;
  text-align: center;
  font-size: 14px;
  line-height: 1.5;
  color: rgba(254, 254, 254, .88);
  text-wrap: pretty;
}

.lightbox__btn {
  position: absolute;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1px solid rgba(254, 254, 254, .28);
  background: rgba(28, 24, 32, .72);
  color: #FEFEFE;
  cursor: pointer;
  transition: background-color .15s, border-color .15s;
}
.lightbox__btn:hover { background: var(--purple); border-color: var(--purple); }
.lightbox__btn:focus-visible { outline: 3px solid #FEFEFE; outline-offset: 2px; }

.lightbox__close { top: -6px; right: -6px; }
.lightbox__nav { top: 50%; transform: translateY(-50%); }
.lightbox__nav--prev { left: -8px; }
.lightbox__nav--next { right: -8px; }

@media (max-width: 720px) {
  .lightbox { width: 100vw; max-height: 100vh; }
  .lightbox__img { max-height: 72vh; }
  .lightbox__close { top: 6px; right: 10px; }
  .lightbox__nav { top: auto; bottom: 10px; transform: none; }
  .lightbox__nav--prev { left: 20px; }
  .lightbox__nav--next { right: 20px; }
  .lightbox__caption { padding: 0 16px 62px; }
}

/* --------------------------------------------------------------------------
   8. Assessor / verification panel
   -------------------------------------------------------------------------- */
.panel {
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--bg);
  padding: clamp(28px, 3.4vw, 44px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: clamp(28px, 4vw, 56px);
  align-items: center;
  box-shadow: var(--shadow);
}

.panel__head {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 16px;
}
.panel__icon {
  width: 44px; height: 44px;
  flex-shrink: 0;
  border-radius: 11px;
  background: var(--purple-wash);
  display: flex;
  align-items: center;
  justify-content: center;
}
.panel__head h2 {
  font-size: clamp(26px, 2.8vw, 32px);
  letter-spacing: -.03em;
  font-weight: 700;
  margin: 0;
}
.panel__lede {
  font-size: 17px;
  color: var(--muted);
  margin: 0 0 24px;
  max-width: 420px;
  text-wrap: pretty;
}

.spec { margin: 0; display: flex; flex-direction: column; }
.spec__row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 24px;
  justify-content: space-between;
  padding: 16px 0;
  border-top: 1px solid var(--line-3);
}
.spec__row:last-child { border-bottom: 1px solid var(--line-3); }
.spec__key {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-3);
}
.spec__val { font-size: 16.5px; font-weight: 700; color: var(--ink); margin: 0; }
.spec__val--mono {
  font-family: var(--mono);
  font-weight: 500;
  color: var(--purple);
}

/* --------------------------------------------------------------------------
   9. Pricing
   -------------------------------------------------------------------------- */
.plans { align-items: stretch; }

.plan {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 32px;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  position: relative;
}
.plan--featured { border: 2px solid var(--purple); }

.plan__flag {
  position: absolute;
  top: -12px; left: 32px;
  background: var(--purple);
  color: var(--on-dark);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 5px 11px;
  border-radius: 6px;
}
.plan h3 {
  font-size: 20px;
  letter-spacing: -.025em;
  font-weight: 700;
  margin: 0 0 6px;
}
.plan__for { font-size: 14.5px; color: var(--muted-2); margin: 0 0 24px; }
.plan__price {
  font-family: var(--display);
  font-weight: 700;
  font-size: 42px;
  letter-spacing: -.04em;
  color: var(--ink);
  margin-bottom: 24px;
}
.plan--featured .plan__price { color: var(--purple); }
.plan__price small {
  font-size: 15px;
  font-weight: 600;
  color: var(--muted-2);
  letter-spacing: 0;
}

.ticks {
  display: flex;
  flex-direction: column;
  gap: 11px;
  font-size: 15.5px;
  margin: 0 0 28px;
  padding: 0;
  list-style: none;
}
.ticks li { display: flex; gap: 11px; }
.ticks li::before { content: '\2713'; color: var(--purple); flex-shrink: 0; }

.plan .btn { margin-top: auto; }

.note {
  margin-top: 28px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
  justify-content: space-between;
  border: 1px solid var(--line-3);
  background: var(--bg-tint-2);
  border-radius: 14px;
  padding: 22px 26px;
}
.note p { font-size: 16px; color: var(--muted); margin: 0; max-width: 720px; text-wrap: pretty; }
.note strong { color: var(--ink); }

/* --------------------------------------------------------------------------
   10. Audience cards
   -------------------------------------------------------------------------- */
.who {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 30px;
  display: flex;
  flex-direction: column;
}
.who__n {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--counter);
  margin-bottom: 18px;
}
.who h3 {
  font-size: 21px;
  letter-spacing: -.025em;
  font-weight: 700;
  margin: 0 0 12px;
}
.who p { font-size: 16px; color: var(--muted); margin: 0 0 20px; }
.who__tag { margin-top: auto; font-size: 14.5px; color: var(--muted-2); font-weight: 600; }

/* --------------------------------------------------------------------------
   11. Services (dark)
   -------------------------------------------------------------------------- */
.services {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: clamp(28px, 3vw, 48px);
}
.service { border-top: 2px solid #6C6C6A; padding-top: 28px; }
.service--lead { border-top-color: var(--purple); }
.service h3 {
  font-size: 26px;
  letter-spacing: -.03em;
  font-weight: 700;
  margin: 0 0 14px;
}
.service p { font-size: 17px; color: var(--on-dark-body); margin: 0 0 26px; text-wrap: pretty; }

.arrows {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 16px;
  margin: 0 0 28px;
  padding: 0;
  list-style: none;
}
.arrows li { display: flex; gap: 12px; }
.arrows li::before { content: '\2192'; color: var(--purple-onDark); flex-shrink: 0; }

.service__price {
  font-family: var(--display);
  font-weight: 700;
  font-size: 22px;
  color: var(--on-dark);
}

/* --------------------------------------------------------------------------
   12. Process
   -------------------------------------------------------------------------- */
.steps { grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: clamp(24px, 3vw, 44px); }

.step__head {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 20px;
}
.step__n {
  width: 40px; height: 40px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--purple);
  color: var(--on-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: 16px;
}
.step__rule { flex: 1; height: 1px; background: var(--line-3); }
.step h3 { font-size: 21px; letter-spacing: -.025em; font-weight: 700; margin: 0 0 10px; }
.step p { font-size: 16.5px; color: var(--muted); margin: 0; }


/* --------------------------------------------------------------------------
   12b. Areas covered
   Borough list — real on-page signal for "EPC <borough>" searches, and a
   genuine answer to "do you cover me?".
   -------------------------------------------------------------------------- */
.areas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(190px, 100%), 1fr));
  gap: 8px 18px;
  margin: 0 0 26px;
  padding: 0;
  list-style: none;
}
.areas li {
  position: relative;
  padding-left: 18px;
  font-size: 15.5px;
  color: var(--body);
}
.areas li::before {
  content: '';
  position: absolute;
  left: 0; top: .62em;
  width: 7px; height: 7px;
  border-radius: 2px;
  background: var(--purple);
  opacity: .55;
}
.areas__note {
  margin: 0;
  font-size: 16px;
  color: var(--muted);
  max-width: 70ch;
  text-wrap: pretty;
}
@media (max-width: 720px) {
  .areas { gap: 6px 14px; }
  .areas li { font-size: 14.5px; }
  .areas__note { font-size: 15px; }
}

/* --------------------------------------------------------------------------
   13. Reviews
   -------------------------------------------------------------------------- */
/* --- Reviews banner ------------------------------------------------------
   The score is the point of this section, so it leads at display size with
   the heading and CTA arranged around it. --------------------------------- */
.reviews__banner {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 20px 30px;
  margin-bottom: 26px;
  padding: 24px 28px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background:
    radial-gradient(120% 160% at 0% 0%, rgba(118,47,163,.10) 0%, rgba(118,47,163,0) 58%),
    linear-gradient(180deg, #FFFFFF 0%, #FCFAFD 100%);
  box-shadow: 0 14px 40px rgba(44, 44, 43, .06);
}

.reviews__bannerScore {
  display: flex;
  align-items: center;
  gap: 16px;
  padding-right: 30px;
  border-right: 1px solid var(--line-2);
}
.reviews__big {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(56px, 7vw, 76px);
  line-height: .82;
  letter-spacing: -.05em;
  color: var(--purple);
}
.reviews__bigMeta { display: flex; flex-direction: column; gap: 5px; }
.reviews__bigStars { color: var(--star); font-size: 19px; letter-spacing: 3px; line-height: 1; }
.reviews__bigCount {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted-2);
}

.reviews__bannerBody { min-width: 0; }
.reviews__title { margin: 0 0 8px; font-size: clamp(26px, 3vw, 36px); }
.reviews__blurb { margin: 0; font-size: 16px; color: var(--muted); text-wrap: pretty; }
.reviews__cta { white-space: nowrap; }

@media (max-width: 900px) {
  .reviews__banner { grid-template-columns: minmax(0, 1fr); padding: 20px; gap: 16px; }
  .reviews__bannerScore { padding-right: 0; padding-bottom: 16px; border-right: 0; border-bottom: 1px solid var(--line-2); }
  .reviews__cta { justify-self: stretch; }
}

.reviews__rail {
  position: relative;
  overflow-x: hidden;
  overflow-x: clip;
}

.reviews__track {
  display: flex;
  gap: 18px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-left: 2px;
  padding: 2px 2px 14px;
  scrollbar-width: thin;
  scrollbar-color: #CFC3D8 transparent;
}
.reviews__track::-webkit-scrollbar { height: 8px; }
.reviews__track::-webkit-scrollbar-track { background: transparent; }
.reviews__track::-webkit-scrollbar-thumb { background: #CFC3D8; border-radius: 100px; }

.review {
  flex: 0 0 min(348px, 84vw);
  scroll-snap-align: start;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px;
  box-shadow: 0 4px 16px rgba(44, 44, 43, .04);
  transition: border-color .16s, box-shadow .16s, transform .16s;
  display: flex;
  flex-direction: column;
  margin: 0;
}
.review:hover {
  border-color: #DFD4E8;
  box-shadow: 0 10px 26px rgba(44, 44, 43, .09);
  transform: translateY(-2px);
}
.review__stars { color: var(--star); font-size: 13.5px; letter-spacing: 2px; margin: 0 0 10px; }
.review blockquote {
  margin: 0 0 16px;
  font-size: 15.5px;
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
  /* Several reviewers used line breaks; preserve their formatting without
     letting long lines wrap oddly. */
  white-space: pre-line;
  /* Cards in a row share the tallest card's height. One 400-character review
     was forcing every card to 426px, leaving 276px of dead space under the
     short ones. Capping the quote pulls the whole row in; the full text is a
     click away on the Google listing. */
  display: -webkit-box;
  -webkit-line-clamp: 8;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* --- Read more ------------------------------------------------------------
   The control sits ON the last clipped line rather than under it. In normal
   flow it would add ~30px to the tallest card, and since the rail stretches
   every card to match, all 15 would grow by that much. This way the cards keep
   exactly the height they had. The gradient blends it into the fading text so
   it reads as "…more" rather than a bolted-on button.
   -------------------------------------------------------------------------- */
.review__quote { position: relative; margin: 0 0 16px; }
.review__quote blockquote { margin: 0; }

.review__more {
  position: absolute;
  right: 0;
  bottom: 0;
  border: 0;
  /* A long fade so the clipped word underneath dissolves into the button
     rather than stopping mid-letter against a hard edge. */
  padding: 0 0 0 62px;
  font-family: var(--sans);
  font-size: 15.5px;
  line-height: 1.55;
  font-weight: 700;
  color: var(--purple);
  cursor: pointer;
  background: linear-gradient(90deg, rgba(254, 254, 254, 0) 0%, var(--bg) 58%);
}
.review__more:hover { color: var(--purple-dark); }
.review__more::after { content: ' ›'; }

/* --- Full-review dialog ---------------------------------------------------- */
.review-modal {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: min(560px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  overflow: visible;
}
.review-modal::backdrop { background: rgba(44, 44, 43, .55); }

.review-modal__panel {
  position: relative;
  background: var(--bg);
  border-radius: 20px;
  padding: clamp(24px, 3.4vw, 36px);
  box-shadow: 0 24px 60px rgba(44, 44, 43, .22);
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.review-modal blockquote {
  margin: 0 0 22px;
  font-size: 16.5px;
  line-height: 1.6;
  color: var(--body);
  white-space: pre-line;
  text-wrap: pretty;
}
.review-modal__by { display: flex; align-items: center; gap: 11px; }

.review-modal__close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}
.review-modal__close:hover { background: var(--purple-wash); color: var(--ink); }

.review figcaption {
  margin-top: auto;
  padding-top: 4px;
  display: flex;
  align-items: center;
  gap: 11px;
}
.review__avatar {
  width: 36px; height: 36px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--purple-wash);
  color: var(--purple);
  display: grid;
  place-items: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: 15px;
}
.review__who { display: flex; flex-direction: column; min-width: 0; }
.review__name { font-size: 14.5px; font-weight: 700; color: var(--ink); }
.review__when { font-size: 12.5px; color: var(--muted-3); }

.reviews__controls {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
}
.reviews__btn {
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1.5px solid var(--outline);
  background: var(--bg);
  color: var(--body);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: border-color .15s, color .15s, opacity .15s;
}
.reviews__btn:hover:not([disabled]) { border-color: var(--purple); color: var(--purple); }
.reviews__btn[disabled] { opacity: .35; cursor: default; }
.reviews__hint { font-size: 13.5px; color: var(--muted-3); }

/* Shown until reviews are actually connected (see main.js + reviews.json). */
.reviews__empty {
  border: 1px dashed #D9CFE2;
  border-radius: var(--radius);
  background: var(--bg);
  padding: clamp(32px, 4vw, 48px);
  text-align: center;
}
.reviews__empty .eyebrow { color: var(--plan-ink); margin-bottom: 12px; }
.reviews__empty p { font-size: 17px; color: var(--muted); margin: 0 auto; max-width: 520px; text-wrap: pretty; }
.reviews__empty .btn { margin-top: 22px; }

/* --- What to have ready ------------------------------------------------ */
/* Six items, so the column count is pinned rather than left to auto-fit —
   otherwise wide screens give 5 across and leave a single orphan on row two.
   3×2 → 2×3 → 1×6. */
.ready-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}
@media (max-width: 900px) { .ready-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .ready-grid { grid-template-columns: minmax(0, 1fr); } }
.ready-item {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 20px;
}
.ready-item__icon {
  width: 42px; height: 42px;
  flex-shrink: 0;
  border-radius: 11px;
  background: var(--purple-wash);
  color: var(--purple);
  display: grid;
  place-items: center;
}
.ready-item__icon svg { display: block; }
.ready-item h3 {
  font-size: 16.5px;
  font-weight: 700;
  letter-spacing: -.02em;
  margin: 0 0 4px;
}
.ready-item p { font-size: 14.5px; color: var(--muted-2); margin: 0; }

.ready-note {
  margin-top: 22px;
  font-size: 15.5px;
  color: var(--muted);
  background: var(--bg-tint-2);
  border: 1px solid var(--line-3);
  border-radius: 14px;
  padding: 18px 22px;
  text-wrap: pretty;
}
.ready-note strong { color: var(--ink); }

/* --- Agents & partners -------------------------------------------------- */
.partners {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: clamp(32px, 4vw, 64px);
  align-items: center;
}
.partner-points {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.partner-point {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  background: rgba(254, 254, 254, .06);
  border: 1px solid rgba(254, 254, 254, .16);
  border-radius: 13px;
  padding: 17px 19px;
}
.partner-point__n {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--purple-onDark);
  flex-shrink: 0;
  padding-top: 2px;
}
.partner-point b { display: block; font-size: 16px; color: var(--on-dark); margin-bottom: 3px; }
.partner-point span { font-size: 14.5px; color: var(--on-dark-body); }

/* --------------------------------------------------------------------------
   14. EPC basics

   The left column once held an eyebrow, an h2, a lede and a single link while
   the right held eight FAQ items — a 1 : 5.9 height ratio that left a long
   void beside the questions. It now carries the A–G rating scale from the
   certificate itself, and sticks alongside the list on desktop. The split is
   deliberately uneven (5 : 7) so the taller FAQ column runs shorter.
   -------------------------------------------------------------------------- */
.basics-row {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(32px, 4.5vw, 68px);
  align-items: start;
}
.basics-aside .lede { max-width: 46ch; }

/* Sticky is gated on the aside actually fitting while pinned. Measured worst
   case is the narrowest two-column width (981px), where the aside is 731px and
   the 98px offset puts the requirement at 829 — hence the 840 gate. Below it
   the aside stays in normal flow: a pinned column taller than the window shows
   a cropped bottom for most of the scroll, which is worse than not sticking.
   Re-measure this gate if anything is added to the aside. */
@media (min-width: 981px) and (min-height: 840px) {
  .basics-aside { position: sticky; top: calc(var(--header-h) + 28px); }
}

.faq { display: flex; flex-direction: column; }
.faq__item { padding: 24px 0; border-top: 1px solid var(--line-4); }
.faq__item:last-child { border-bottom: 1px solid var(--line-4); }
.faq__item h3 { font-size: 18px; font-weight: 700; letter-spacing: -.02em; margin: 0 0 8px; }
.faq__item p { font-size: 16px; color: var(--muted); margin: 0; }

/* --- A–G rating scale ------------------------------------------------------
   Band colours are the official EPC palette, sampled straight out of
   assets/samples/epc-certificate.jpg so the graphic matches the document a
   customer actually receives. They are NOT part of the site's palette and must
   not be "branded" purple — the colours are what makes the chart recognisable.

   Contrast: the letters use a near-black on every band except G, where red at
   #E9153B gives only 3.7:1 against ink. White clears 4.53:1 there, so band G
   flips its letter colour via --band-ink.
   -------------------------------------------------------------------------- */
.epc-scale {
  margin: 26px 0 0;
  padding: 16px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.epc-scale__cap {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-3);
  margin: 0 0 12px;
}
.epc-scale__bands { list-style: none; margin: 0; padding: 0; }

.epc-scale__band {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  align-items: stretch;
  min-height: 32px;
}
.epc-scale__band + .epc-scale__band { margin-top: 3px; }

.epc-scale__score {
  display: grid;
  place-items: center;
  background: var(--band-tint);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 700;
  border-radius: 5px 0 0 5px;
}

/* The bar is a percentage of the 1fr track, so the ramp holds its shape at any
   column width; min-width keeps the "A" bar wide enough to seat its letter. */
.epc-scale__bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  width: var(--band-w);
  min-width: 54px;
  padding: 0 12px;
  background: var(--band);
  border-radius: 0 5px 5px 0;
}
.epc-scale__letter {
  font-family: var(--display);
  font-size: 19px;
  font-weight: 800;
  line-height: 1;
  color: var(--band-ink, #1D1D1C);
}

.epc-scale__band--a { --band: #00C781; --band-tint: #73E0BA; --band-w: 22%; }
.epc-scale__band--b { --band: #19B459; --band-tint: #81D6A4; --band-w: 35%; }
.epc-scale__band--c { --band: #8DCE46; --band-tint: #C0E499; --band-w: 48%; }
.epc-scale__band--d { --band: #FFD500; --band-tint: #FFE873; --band-w: 61%; }
.epc-scale__band--e { --band: #FCAA65; --band-tint: #FDD0AA; --band-w: 74%; }
.epc-scale__band--f { --band: #EF8023; --band-tint: #F6B986; --band-w: 87%; }
/* Pure #FFF here, not the site's off-white --bg: on #E9153B that one step is
   the difference between 4.49:1 and 4.53:1. */
.epc-scale__band--g { --band: #E9153B; --band-tint: #F37E93; --band-w: 100%; --band-ink: #FFFFFF; }

.epc-scale__foot {
  font-size: 14.5px;
  color: var(--muted);
  margin: 12px 0 0;
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   15. Quote form
   -------------------------------------------------------------------------- */
/* The quote row previously paired a short left column with a tall form, which
   left a large void underneath it. The aside now carries its own weight —
   contact details plus what happens next — and sticks alongside the form on
   desktop so the two columns stay optically balanced. */
.quote-row {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: clamp(28px, 3.5vw, 56px);
  align-items: start;
}

.quote-aside { position: sticky; top: calc(var(--header-h) + 28px); }
.quote-aside .lede { margin-bottom: 26px; max-width: 42ch; }

.quote-contact {
  display: grid;
  gap: 2px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 6px 20px;
  margin-bottom: 22px;
}
.quote-contact__row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 18px;
  padding: 14px 0;
}
.quote-contact__row + .quote-contact__row { border-top: 1px solid var(--line-3); }
.quote-contact__k {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-3);
  margin: 0;
}
.quote-contact__v { font-size: 16.5px; font-weight: 700; color: var(--ink); margin: 0; text-align: right; }
.quote-contact__v--plain { font-weight: 500; color: var(--body); }

.next-steps {
  display: grid;
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}
.next-steps li {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  font-size: 15.5px;
  color: var(--muted);
}
.next-steps li::before {
  counter-increment: step;
  content: counter(step);
  width: 26px; height: 26px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--purple-wash);
  color: var(--purple);
  display: grid;
  place-items: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: 12.5px;
  margin-top: 1px;
}
.next-steps b { color: var(--ink); font-weight: 700; }

.form-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: clamp(26px, 3vw, 38px);
}

.form { display: flex; flex-direction: column; gap: 18px; }
.form__row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 18px;
}

.field { display: flex; flex-direction: column; gap: 7px; }
.field > span { font-size: 13.5px; font-weight: 700; color: var(--body); }
.field > span .opt { font-weight: 500; color: var(--muted-3); }

.field input,
.field select,
.field textarea {
  border: 1.5px solid var(--field);
  border-radius: 9px;
  padding: 12px 14px;
  font-size: 15.5px;
  color: var(--ink);
  background: var(--bg);
  transition: border-color .15s, box-shadow .15s;
}
.field textarea { resize: vertical; min-height: 88px; }
.field input::placeholder,
.field textarea::placeholder { color: #97919C; }

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--purple);
  box-shadow: 0 0 0 3px rgba(118, 47, 163, .15);
}
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible { outline: none; }

/* Only flag invalid fields after a submit attempt, never while typing. */
.form.was-submitted .field input:invalid,
.form.was-submitted .field select:invalid,
.form.was-submitted .field textarea:invalid {
  border-color: #B3261E;
  box-shadow: 0 0 0 3px rgba(179, 38, 30, .12);
}

/* Honeypot — hidden from people, visible to naive bots. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

.form__submit { padding: 15px; font-size: 16.5px; }
.form__submit[disabled] { opacity: .6; cursor: progress; }

.form__small { font-size: 13px; color: var(--muted-3); margin: 0; text-align: center; }
.form__small a { color: var(--muted-3); text-decoration: underline; }
.form__small a:hover { color: var(--purple); }

.form__error {
  margin: 0;
  font-size: 14.5px;
  font-weight: 600;
  color: #B3261E;
  background: #FCEFEE;
  border: 1px solid #F3CFCC;
  border-radius: 9px;
  padding: 12px 14px;
}
.form__error[hidden] { display: none; }

.form-done {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
  padding: 34px 0;
}
.form-done__tick {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: #F2E8F8;
  color: var(--purple);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: 800;
}
.form-done h3 { font-size: 24px; font-weight: 700; letter-spacing: -.02em; margin: 0; }
.form-done p { font-size: 16.5px; color: var(--muted); margin: 0; }

/* --------------------------------------------------------------------------
   16. Footer
   -------------------------------------------------------------------------- */
.footer {
  background: var(--dark);
  color: var(--on-dark-body);
  padding: clamp(48px, 5vw, 72px) var(--gutter) 30px;
}
.footer__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
  gap: 40px;
  padding-bottom: 36px;
  border-bottom: 1px solid var(--dark-2);
}
.footer__brand {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-bottom: 16px;
  color: var(--on-dark);
}
.footer__brand:hover { color: var(--on-dark); }
/* Exactly the same logo file as the navbar, in the exact brand colours. The
   footer background is #494948 — identical to the monogram's charcoal — so it
   sits on a light chip rather than being recoloured, which keeps #762FA3 and
   #494948 intact everywhere the logo appears. */
.footer__brand img {
  height: 30px;
  width: auto;
  display: block;
  flex-shrink: 0;
  box-sizing: content-box;
  padding: 7px 9px;
  background: #FEFEFE;
  border-radius: 10px;
}
.footer__brand span {
  font-family: var(--display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -.03em;
}
.footer__blurb { font-size: 15px; color: var(--on-dark-muted); margin: 0; max-width: 270px; }

.footer h2 {
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 400;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--on-dark-muted);
  margin: 0 0 14px;
}
.footer__list {
  display: flex;
  flex-direction: column;
  gap: 9px;
  font-size: 15px;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--on-dark-link);
}
.footer__list a { color: var(--on-dark-link); }
.footer__list a:hover { color: var(--on-dark); }
.footer__text { font-size: 15px; color: var(--on-dark-link); }

.footer__creds {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 20px;
  margin: 0;
  padding: 22px 0;
  border-bottom: 1px solid var(--dark-2);
  list-style: none;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--on-dark-muted);
}
.footer__creds li { display: flex; align-items: center; gap: 20px; }
.footer__creds li:not(:last-child)::after { content: '\00B7'; color: #6C6C6A; }

.footer__base {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: space-between;
  padding-top: 22px;
  font-size: 13.5px;
  color: var(--on-dark-muted);
}
.footer__base a { color: var(--on-dark-muted); text-decoration: underline; }
.footer__base a:hover { color: var(--on-dark); }

/* --------------------------------------------------------------------------
   16b. Cookie consent
   Non-essential storage stays off until "Accept" is pressed (PECR reg. 6 /
   UK GDPR). The consent choice itself is strictly necessary, so remembering
   it does not require consent.
   -------------------------------------------------------------------------- */
.cookie {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 120;
  padding: 14px var(--gutter);
  background: rgba(254, 254, 254, .97);
  border-top: 1px solid var(--line);
  box-shadow: 0 -10px 34px rgba(44, 44, 43, .12);
}
@supports (backdrop-filter: blur(10px)) {
  .cookie { background: rgba(254, 254, 254, .92); backdrop-filter: blur(10px); }
}

.cookie__inner {
  max-width: var(--wrap);
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 28px;
  justify-content: space-between;
}

.cookie__text {
  margin: 0;
  flex: 1 1 min(560px, 100%);
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
}
.cookie__text strong { color: var(--ink); }

.cookie__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  flex-shrink: 0;
}
.cookie__actions .btn { padding: 11px 18px; font-size: 14.5px; }

/* Re-opens the banner so a choice can be withdrawn or changed. */
.cookie-reopen {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--on-dark-muted);
  text-decoration: underline;
  cursor: pointer;
}
.cookie-reopen:hover { color: var(--on-dark); }

@media (max-width: 720px) {
  .cookie { padding: 14px var(--gutter) 16px; max-height: 70vh; overflow-y: auto; }
  .cookie__text { font-size: 13.5px; }
  .cookie__actions { width: 100%; }
  .cookie__actions .btn { flex: 1 1 auto; }
}

/* --------------------------------------------------------------------------
   17. Prose (privacy page)
   -------------------------------------------------------------------------- */
.prose { max-width: 720px; }
.prose h2 {
  font-family: var(--display);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -.03em;
  margin: 40px 0 12px;
}
.prose h2:first-of-type { margin-top: 32px; }
.prose p, .prose li { font-size: 17px; color: var(--muted); }
.prose ul { padding-left: 20px; }
.prose li { margin-bottom: 8px; }
.prose__updated {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted-3);
}

/* --------------------------------------------------------------------------
   18. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1100px) {
  .nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px var(--gutter) 20px;
    background: var(--bg);
    border-bottom: 1px solid var(--line-2);
    box-shadow: 0 18px 30px rgba(44, 44, 43, .07);
    max-height: calc(100vh - var(--header-h));
    overflow-y: auto;
  }
  .nav.is-open { display: flex; }

  .nav__sep { display: none; }

  .nav__link,
  .nav__tel {
    padding: 14px 2px;
    font-size: 16px;
    border-radius: 0;
    border-bottom: 1px solid var(--line-2);
  }
  .nav__link::after { display: none; }
  .nav__cta { margin-top: 16px; text-align: center; padding: 14px 20px; font-size: 16px; }
  .nav-toggle { display: flex; }
  .header__inner { position: relative; gap: 16px; }

  /* Sub-pages carry a single CTA instead of a menu, so they opt out of the
     drop-down panel entirely and stay inline in the bar at every width. */
  .nav--simple {
    display: flex;
    position: static;
    flex-direction: row;
    align-items: center;
    margin-left: auto;
    padding: 0;
    background: none;
    border: 0;
    box-shadow: none;
    max-height: none;
    overflow: visible;
  }
  .nav--simple .nav__cta { margin-top: 0; padding: 11px 18px; font-size: 14.5px; }
}

/* --- Tablet ------------------------------------------------------------- */
@media (max-width: 980px) {
  .quote-row { grid-template-columns: 1fr; gap: 32px; }
  .quote-aside { position: static; }
  .quote-aside .lede { max-width: none; }

  .basics-row { grid-template-columns: 1fr; gap: 34px; }
  .basics-aside .lede { max-width: none; }
  /* Stacked, the scale no longer has to prop up a column — cap it so it does
     not stretch into a banner above the questions. */
  .epc-scale { max-width: 460px; }

  /* The 262px contact rail gets cramped long before the text column does. */
  .hero__aside { flex: 1 1 100%; }
  .hero__cols { align-items: flex-start; }
  .hero { min-height: 0; padding-top: clamp(64px, 9vw, 110px); }
  .hero__aside .contact-cards { flex-direction: row; flex-wrap: wrap; }
  .hero__aside .contact-card { flex: 1 1 260px; }

  .panel { gap: 28px; }
  .reviews__banner { gap: 16px 20px; }
}

/* --- Mobile ------------------------------------------------------------- */
@media (max-width: 720px) {
  :root { --gutter: 20px; }

  body { font-size: 16px; }

  .section { padding: clamp(48px, 11vw, 68px) var(--gutter); }
  .h2 { font-size: clamp(26px, 7.2vw, 32px); }
  .lede { font-size: 16.5px; }
  .section-head { margin-bottom: 30px; }

  /* The horizontal wash would leave stacked text sitting on deep purple, so
     the ramp turns vertical and the floor plan drops to a corner motif. */
  .hero {
    padding-top: 44px;
    padding-bottom: 40px;
    background-image:
      url('hero-bg.svg'),
      linear-gradient(168deg, #FEFEFE 0%, #FBF8FC 38%, #EFE6F4 68%, #DFCCEC 100%);
    background-position: right -70px bottom -40px, 0 0;
    background-size: auto 46%, cover;
  }
  .hero::before {
    background: linear-gradient(180deg, rgba(254,254,254,.94) 0%, rgba(254,254,254,.62) 55%, rgba(254,254,254,.3) 100%);
  }
  .hero h1 { font-size: clamp(31px, 8.4vw, 40px); margin-bottom: 16px; }
  .hero__lede { font-size: 17px; margin-bottom: 22px; }
  .hero__eyebrow { margin-bottom: 16px; }

  .stats { gap: 8px; margin-bottom: 22px; }
  .stat { padding: 7px 13px; }
  .stat b { font-size: 14px; }
  .stat span { font-size: 12.5px; }

  .hero__actions { gap: 10px; margin-bottom: 20px; }
  .hero__actions .btn { flex: 1 1 100%; }
  .btn--lg { padding: 15px 26px; font-size: 16px; }

  .proof { gap: 8px; margin-bottom: 22px; }
  .proof > li { flex: 1 1 100%; }

  .trust { font-size: 10.5px; gap: 6px 12px; }
  .trust li { gap: 12px; }

  .hero__aside .contact-card { flex: 1 1 100%; }

  .plan, .who, .form-card, .panel, .ready-item { padding: 22px; }
  .plan__flag { left: 22px; }
  .note { padding: 20px; }
  .note .link-arrow { font-size: 15.5px; }
  .split-head { gap: 16px; }

  .spec__row { padding: 13px 0; }
  .spec__val { font-size: 15.5px; }

  /* Full width here — the ≤980px cap exists only to stop the scale stretching
     into a banner on tablets, and the column is already narrow by this point. */
  .epc-scale { max-width: none; }
  .epc-scale__band { grid-template-columns: 50px minmax(0, 1fr); }
  .epc-scale__score { font-size: 11px; }
  .epc-scale__letter { font-size: 17.5px; }
  .epc-scale__foot { font-size: 14px; }

  .quote-contact { padding: 4px 16px; }
  .quote-contact__row { padding: 12px 0; }
  .quote-contact__v { font-size: 15.5px; text-align: left; }

  .form__row { grid-template-columns: 1fr; gap: 14px; }
  .form { gap: 14px; }

  .review { padding: 22px; }
  .reviews__track { gap: 14px; }

  .footer__cols { gap: 30px; }
  .footer__base { font-size: 12.5px; gap: 8px; }
}

@media (max-width: 420px) {
  .brand__name { font-size: 17px; }
  .plan__price { font-size: 34px; }
  .hero h1 { letter-spacing: -.03em; }
  .proof-badge__meta { font-size: 11.5px; }
}

/* --------------------------------------------------------------------------
   19. Sub-page furniture
   Shared by pricing / areas / faq / about / guides. The homepage doesn't use
   any of it, so nothing here can regress the one-pager.
   -------------------------------------------------------------------------- */

/* Page header block. Sits tight under the sticky header, so it carries less
   top padding than a mid-page .section would. */
.section--head { padding-top: clamp(28px, 3.4vw, 44px); padding-bottom: 0; }

.h1-page {
  font-family: var(--display);
  font-size: clamp(32px, 4vw, 50px);
  line-height: 1.08;
  font-weight: 700;
  letter-spacing: -.035em;
  color: var(--ink);
  margin: 0 0 18px;
  text-wrap: balance;
}
.lede--wide { max-width: 70ch; font-size: 18.5px; }

/* --- Breadcrumbs --------------------------------------------------------- */
.crumbs { margin-bottom: 20px; }
.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.crumbs li { display: flex; align-items: center; gap: 8px; }
.crumbs li + li::before {
  content: '/';
  color: var(--muted-3);
  opacity: .65;
}
.crumbs a { color: var(--muted-3); }
.crumbs a:hover { color: var(--purple); }
.crumbs [aria-current='page'] { color: var(--ink); font-weight: 500; }

/* --- Closing call to action ---------------------------------------------- */
.endcta {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(24px, 3vw, 48px);
  align-items: center;
}
.endcta .lede { max-width: 56ch; }
.endcta__actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* --- Guides -------------------------------------------------------------- */
.guide-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 22px;
}
.guide-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px;
  color: inherit;
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.guide-card:hover {
  border-color: var(--purple-soft);
  box-shadow: var(--shadow);
  transform: translateY(-2px);
  color: inherit;
}
.guide-card h2 {
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -.025em;
  margin: 0;
  text-wrap: balance;
}
.guide-card p { font-size: 16px; color: var(--muted); margin: 0; flex: 1 1 auto; }
.guide-card .link-arrow { color: var(--purple); }

/* Article footer CTA. Constrained to the prose measure so it reads as the end
   of the article rather than a new section. */
.guide-cta {
  max-width: 720px;
  margin-top: 44px;
  padding: 28px;
  background: var(--purple-wash);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.guide-cta h2 {
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -.025em;
  margin: 0 0 8px;
}
.guide-cta p { font-size: 16px; color: var(--muted); margin: 0 0 18px; }
.guide-cta__actions { display: flex; flex-wrap: wrap; gap: 12px; }

.prose h3 {
  font-family: var(--display);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.025em;
  margin: 28px 0 10px;
}
.prose ol { padding-left: 20px; }
.prose ol li { margin-bottom: 8px; }
.prose strong { color: var(--ink); }

/* --- Areas, grouped by region -------------------------------------------- */
.area-groups { display: grid; gap: clamp(28px, 3.4vw, 44px); }
.area-group h3 {
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -.025em;
  margin: 0 0 8px;
}
.area-group > p {
  font-size: 16.5px;
  color: var(--muted);
  margin: 0 0 18px;
  max-width: 68ch;
  text-wrap: pretty;
}
.areas--compact { margin: 0; }

/* --- FAQ page ------------------------------------------------------------ */
.faq-block + .faq-block { margin-top: clamp(36px, 4vw, 56px); }
.h2--sm { font-size: clamp(22px, 2.4vw, 28px); margin-bottom: 12px; }
/* On a dedicated FAQ page the answers get the full column, so they need a
   readable measure rather than the homepage's narrow one. */
.faq--wide .faq__item p { max-width: 78ch; }

/* --------------------------------------------------------------------------
   20. Motion & print
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

@media print {
  .header, .nav-toggle, .hero__actions, .form-card, .skip { display: none !important; }
  body { font-size: 12pt; color: #000; }
  .section, .hero { padding: 12pt 0; }
  .hero::before { display: none; }
  a[href^='http']::after { content: ' (' attr(href) ')'; font-size: 9pt; word-break: break-all; }
  /* The rating scale is nothing but background colour — without this it prints
     as seven empty rows. */
  .epc-scale__score,
  .epc-scale__bar { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
}

/* --------------------------------------------------------------------------
   21. Mobile polish

   Every rule below lives inside a max-width media query, so the desktop
   rendering is untouched by construction. That was verified rather than
   assumed: every element on all 10 pages was fingerprinted at 1440px and
   1280px (geometry + 24 computed properties) before and after this section
   was added, and the hashes are identical. See README §12.
   -------------------------------------------------------------------------- */

/* --- Tablet down --------------------------------------------------------- */
@media (max-width: 820px) {
  /* The closing CTA was `minmax(0, 1fr) auto`. Once the two buttons no longer
     fit beside the text, minmax(0,…) let the text column collapse to 0px wide
     and 748px tall — the heading wrapped one character per line. Stack it. */
  .endcta { grid-template-columns: 1fr; align-items: start; }
  .endcta .lede { max-width: none; }
}

/* --- Phones -------------------------------------------------------------- */
@media (max-width: 720px) {
  /* iOS Safari zooms the entire page when a focused field is under 16px, and
     never zooms back out. This is the single biggest cause of the "awkward
     zooming" on a phone. 16px is the threshold, not a preference — the fields
     look near enough identical. */
  .field input,
  .field select,
  .field textarea { font-size: 16px; }

  /* Stop iOS rendering its own rounded chrome over the select. */
  .field select { -webkit-appearance: none; appearance: none; }

  /* Full-width primary actions. Two buttons side by side on a 320px column
     leaves each too narrow to read comfortably. */
  .endcta__actions,
  .guide-cta__actions { flex-direction: column; align-items: stretch; }
  .endcta__actions .btn,
  .guide-cta__actions .btn { width: 100%; text-align: center; }

  /* --- Tap targets -------------------------------------------------------
     These were 18–22px tall because they are inline text links inside lists.
     Padding only: the type size and colour are unchanged, so nothing moves
     visually except the space around the link. WCAG 2.5.8 wants 24×24 as a
     floor; 44px is the comfortable thumb size. */
  .footer__list { gap: 2px; }
  .footer__list a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  .footer__base { gap: 10px 14px; font-size: 13px; }
  .footer__base a,
  .cookie-reopen {
    display: inline-flex;
    align-items: center;
    min-height: 34px;
    font-size: 13px;
  }

  .crumbs ol { gap: 2px 8px; }
  .crumbs a {
    display: inline-flex;
    align-items: center;
    min-height: 32px;
  }

  .link-arrow {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
  }

  /* Phone and email in the quote card are contact actions sitting in a list,
     not links inside a sentence, so they get a proper target. Links that DO
     sit mid-sentence (the "privacy notice" in the cookie text, the number in
     a paragraph) are left alone — WCAG 2.5.8 exempts inline links, and
     padding them would push the surrounding lines apart. */
  .quote-contact__v a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
  }

  /* The cookie banner is a consent control: both choices must be equally
     easy to hit, and neither should need a stretch. */
  .cookie__actions { flex-direction: column; align-items: stretch; gap: 10px; }
  .cookie__actions .btn { width: 100%; min-height: 46px; text-align: center; }

  /* --- Legibility --------------------------------------------------------
     A handful of mono labels sat at 10.5–11px. They are deliberately small,
     but on a phone that crosses from "understated" into "squinting". These
     are the smallest text on the site; a point or so back makes them
     readable without changing the typographic idea. */
  .trust { font-size: 11.5px; }
  .eyebrow { font-size: 12px; }
  .hero__aside-label { font-size: 12px; }
  .footer__cols h2 { font-size: 12px; }
  .footer__creds { font-size: 12px; }
  .prose__updated { font-size: 12.5px; }

  /* Grey flash on tap looks like a rendering fault on a dark section. */
  a, button, summary { -webkit-tap-highlight-color: rgba(118, 47, 163, .12); }

  /* Momentum scrolling for the horizontal rails, and keep the gallery and
     rail from hijacking a vertical swipe. */
  .reviews__track,
  .areas { -webkit-overflow-scrolling: touch; }
  .reviews__track { touch-action: pan-x pan-y; }
}

/* --- Small phones -------------------------------------------------------- */
@media (max-width: 420px) {
  /* Buttons in the hero already go full width; make sure nothing else sits in
     a two-up grid so narrow that the label wraps mid-word. */
  .endcta__actions .btn,
  .guide-cta__actions .btn,
  .cookie__actions .btn { font-size: 15.5px; }
}
