/* FRONT DOOR, the chosen style, shared shell for variants A, B and C.
   Everything here is common to all three. Each variant then changes emphasis,
   pacing, type scale and imagery strategy in its own <style> block.
   The direction is fixed: full bleed photography, one idea per screen,
   very few words, one green. */

/* Reveal on scroll. This is NOT parallax and NOT scroll jacking.
   Nothing moves at a different speed to the page and the scroll is never
   hijacked. Content simply arrives as you reach it, which is the part of
   The Ocean Cleanup that actually reads as expensive. */
/* Gated on the .js class, which front-door.js sets as its very first action.
   Hiding content by default and revealing it with script means that if the
   script is blocked, fails or times out, every heading and paragraph on the
   homepage stays at zero opacity forever. The text is still in the DOM, so a
   raw fetch is fine, but anything that reads rendered visible text sees a blank
   page. No script, no hiding. */
.rv {
  transition: opacity .75s var(--ease), transform .75s var(--ease);
}
.js .rv {
  opacity: 0;
  transform: translateY(20px);
}
.rv.in { opacity: 1; transform: none; }
.rv.d1 { transition-delay: .09s; }
.rv.d2 { transition-delay: .18s; }
.rv.d3 { transition-delay: .27s; }

@media (prefers-reduced-motion: reduce) {
  .rv { opacity: 1; transform: none; transition: none; }
  /* The advice rail's glide is animated in front-door.js, which checks
     prefers-reduced-motion itself and jumps straight to the target instead.
     Nothing to switch off here. */
}

/* Header. Transparent over the hero, warm paper once you leave it. */
header {
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; padding: 20px 34px;
  border-bottom: 1px solid transparent;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
header.stuck { background: var(--paper); border-bottom-color: var(--ink-200); }

/* A transparent header over a photograph is only legible if the photograph
   agrees to it. A bright sky behind the nav measured 2.9:1 against white,
   which fails. This is a short scrim behind the header alone, fading out well
   before it touches the composition, and it disappears the moment the header
   takes its solid paper state. */
header::before {
  content: "";
  position: absolute; inset: 0 0 auto 0; height: 210%;
  z-index: -1; pointer-events: none;
  background: linear-gradient(to bottom, rgba(14,62,34,.78) 0%, rgba(14,62,34,.42) 45%, rgba(14,62,34,0) 100%);
  transition: opacity var(--dur) var(--ease);
}
header.stuck::before { opacity: 0; }
/* The real logo lockup, in both supplied states. The white version shows over
   the hero photograph and the full colour version once the header goes solid.
   No filter and no re-set type: the logo has its own typography and its own
   green (#439854, not the #1F7A47 the interface uses), which is normal for a
   logo. The guardrail is that it is placed, never redrawn. */
header .mark { display: flex; align-items: center; text-decoration: none; }
header .mark img { height: 42px; width: auto; display: block; }
header .mark .logo-dark { display: none; }
header.stuck .mark .logo-light,
.no-hero header .mark .logo-light { display: none; }
header.stuck .mark .logo-dark,
.no-hero header .mark .logo-dark { display: block; }

/* Four top level items, three of which open a menu.
   The submenus open on :hover and :focus-within, which is CSS only, so mouse
   and keyboard both work with the script switched off. The script adds tap,
   Escape and the small screen panel. */
nav { display: flex; align-items: center; gap: 28px; }
.navtop {
  color: var(--white); text-decoration: none; font-size: .9375rem;
  font-weight: 600; padding: 6px 0; border-bottom: 2px solid transparent;
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
}
.navtop:hover { border-bottom-color: currentColor; }
.navtop[aria-current="page"] { border-bottom-color: var(--green-400); }
header.stuck .navtop { color: var(--ink-700); }
header.stuck .navtop[aria-current="page"] { color: var(--green-700); border-bottom-color: var(--green-700); }

.caret {
  width: 7px; height: 7px; margin-top: -3px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); opacity: .7;
  transition: transform var(--dur) var(--ease);
}

/* The group keeps the pointer inside it while the cursor crosses the gap
   between the top item and the panel, which is what the padding-top on the
   panel is for. Without it the menu closes as you move down to it. */
.navgroup { position: relative; }
.navmenu {
  position: absolute; top: 100%; left: 50%; translate: -50% 0;
  margin: 0; padding: 14px 0 0; list-style: none;
  min-width: 250px;
  opacity: 0; visibility: hidden;
  transition: opacity var(--dur) var(--ease), visibility var(--dur) var(--ease);
}
.navmenu::before {
  content: ""; position: absolute; inset: 14px 0 0 0;
  background: var(--white); border: 1px solid var(--ink-200);
  border-radius: var(--r-md); box-shadow: 0 18px 44px rgba(17,17,17,.14);
}
.navmenu li { position: relative; }
.navmenu li + li { border-top: 1px solid var(--ink-100, rgba(17,17,17,.07)); }
.navmenu a {
  position: relative; display: block; padding: 13px 20px;
  color: var(--ink-700); text-decoration: none;
  font-size: .9375rem; font-weight: 600; line-height: 1.35;
}
.navmenu a:hover, .navmenu a:focus-visible { background: var(--green-050); color: var(--green-800); }
.navmenu li:first-child a { border-radius: var(--r-md) var(--r-md) 0 0; }
.navmenu li:last-child a { border-radius: 0 0 var(--r-md) var(--r-md); }

.navgroup:hover > .navmenu,
.navgroup:focus-within > .navmenu,
.navgroup.is-open > .navmenu { opacity: 1; visibility: visible; }
.navgroup:hover > .navtop .caret,
.navgroup:focus-within > .navtop .caret,
.navgroup.is-open > .navtop .caret { transform: rotate(-135deg); }

/* The small screen panel. */
.navpanel {
  position: fixed; inset: 0; z-index: 55;
  background: var(--paper);
  overflow-y: auto;
  padding: 96px 24px 48px;
}
.navpanel[hidden] { display: none; }
.navpanel-inner { max-width: 560px; margin: 0 auto; }
.navpanel-top,
.navpanel-head {
  display: block; padding: 16px 0; border-bottom: 1px solid var(--ink-200);
  font-stretch: 75%; font-weight: 800; letter-spacing: -.01em;
  font-size: 1.25rem; color: var(--ink-900); text-decoration: none;
}
.navpanel-head { color: var(--green-800); }
.navpanel-group ul { list-style: none; margin: 0 0 8px; padding: 0; }
.navpanel-group li { border-bottom: 1px solid var(--ink-200); }
.navpanel-group a { display: block; padding: 14px 0 14px 16px; color: var(--ink-700); text-decoration: none; font-weight: 600; }
.navpanel-group a:hover { color: var(--green-800); }
.navpanel-cta { margin-top: 30px; width: 100%; justify-content: center; }

header .cta {
  background: var(--white); color: var(--green-900); border-radius: var(--r-pill);
  padding: 13px 24px; font-size: .9375rem; font-weight: 700; text-decoration: none;
  white-space: nowrap;
}
header.stuck .cta { background: var(--green-700); color: var(--white); }
header .cta:hover { background: var(--green-100); }
header.stuck .cta:hover { background: var(--green-800); }
.menu-toggle { display: none; }

/* Full bleed screen primitive. */
.screen { position: relative; min-height: 100svh; display: flex; }
.screen > img.bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.screen > .scrim { position: absolute; inset: 0; }
.screen > .inner { position: relative; width: 100%; }

/* Same directional logic as the plates. Sunlit pavement in the lower left of
   the hero measured 2.46:1 against white with a bottom-only gradient, which
   fails even the large-text threshold. The left gradient protects the corner
   the headline lives in; the top band keeps the nav legible against sky. */
.scrim-forest {
  background:
    linear-gradient(to right,
      rgba(14,62,34,.82) 0%, rgba(14,62,34,.64) 30%,
      rgba(14,62,34,.26) 58%, rgba(14,62,34,0) 80%),
    linear-gradient(to top,
      rgba(14,62,34,.90) 0%, rgba(14,62,34,.58) 34%,
      rgba(14,62,34,.10) 66%, rgba(14,62,34,.30) 100%);
}
/* Type on these plates sits bottom left while the subject of the photograph
   sits right, so the scrim is directional rather than a flat band. It protects
   the corner the words live in and leaves the picture alone everywhere else.
   A bright rendered wall behind the headline measured 1.9:1 against white with
   a bottom-only gradient, which fails even the large-text threshold. */
.scrim-ink {
  background:
    linear-gradient(to right,
      rgba(17,17,17,.80) 0%, rgba(17,17,17,.62) 26%,
      rgba(17,17,17,.28) 52%, rgba(17,17,17,0) 74%),
    linear-gradient(to top,
      rgba(17,17,17,.66) 0%, rgba(17,17,17,.24) 46%, rgba(17,17,17,0) 78%);
}

.scroll-hint {
  position: absolute; right: 34px; bottom: 44px; z-index: 2;
  color: rgba(255,255,255,.72); font-size: .8125rem; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
  display: flex; align-items: center; gap: 10px;
}
.scroll-hint span { display: block; width: 1px; height: 46px; background: rgba(255,255,255,.45); }

/* The standard. A running numbered list, never a card grid. */
.standard { padding: 140px 0 150px; background: var(--paper); }
.standard .top { display: flex; flex-wrap: wrap; gap: 40px; align-items: flex-end; justify-content: space-between; }
.standard .top h2 { max-width: 16ch; }
.standard .top p { max-width: 40ch; color: var(--ink-600); margin: 0; }
.standard ol { list-style: none; counter-reset: crit; margin: 84px 0 0; padding: 0; }
.standard li {
  counter-increment: crit; display: grid; grid-template-columns: 92px 1fr;
  gap: 32px; padding: 34px 0; border-top: 1px solid var(--ink-200); align-items: start;
}
.standard li:last-child { border-bottom: 1px solid var(--ink-200); }
.standard li::before {
  content: counter(crit, decimal-leading-zero);
  font-stretch: 75%; font-weight: 800; font-size: 2.25rem; color: var(--green-700); line-height: 1;
}
.standard li h3 { margin-bottom: 10px; }
.standard li p { color: var(--ink-600); font-size: 1.0625rem; max-width: 58ch; margin: 0; }

/* Book a valuation. One central EAN form, forwarded to the area's member. */
.book { background: var(--green-800); color: var(--white); padding: 150px 0; }
.book .inner { max-width: 800px; }
.book h2 { color: var(--white); }
.book p { margin-top: 26px; color: rgba(255,255,255,.85); max-width: 46ch; }
.book form { margin-top: 44px; display: flex; flex-wrap: wrap; gap: 12px; }
.book label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.book input {
  flex: 1 1 260px; font: inherit; font-size: 1.0625rem; padding: 17px 18px;
  border-radius: var(--r-md); border: 1px solid rgba(255,255,255,.35);
  background: rgba(255,255,255,.08); color: var(--white);
}
.book input::placeholder { color: rgba(255,255,255,.6); }
.book input:focus-visible { outline-color: var(--green-400); background: rgba(255,255,255,.14); }
.book .note { margin-top: 20px; font-size: .9375rem; color: rgba(255,255,255,.7); }

/* The agent route. Present on every screenful of the site, never shouting
   over the homeowner it was built for. */
.agents { padding: 110px 0; background: var(--paper); border-top: 1px solid var(--ink-200); }
.agents .inner { display: flex; flex-wrap: wrap; gap: 40px; align-items: center; justify-content: space-between; }
.agents h3 { max-width: 18ch; }
.agents p { margin-top: 14px; color: var(--ink-600); max-width: 46ch; }

/* Blog, as a carousel.
   ⚠️ REBUILT 2026-09-04 from a three row reading list. The old .journal a /
   .when / .what / .go rules went with it: the section now renders the shared
   .card from inc/cards.php, so it inherits the Advice index's card styling and
   only the rail behaviour is defined here. */
.journal { padding: 130px 0 150px; background: var(--paper); border-top: 1px solid var(--ink-200); }
.journal h2 { max-width: 14ch; margin: 0; }

/* Heading and arrows on one line, so the controls are found where the eye
   already is rather than hunted for under the cards. */
.journal-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 28px; flex-wrap: wrap; margin-bottom: 44px;
}
.rail-nav { display: flex; gap: 12px; flex-shrink: 0; }
.rail-btn {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 11px 20px; border-radius: var(--r-pill);
  border: 1px solid var(--ink-200); background: var(--white);
  color: var(--ink-700); font: inherit; font-size: .9375rem; font-weight: 700;
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.rail-btn:hover:not(:disabled) { border-color: var(--green-200); background: var(--green-050); color: var(--green-800); }
/* Disabled rather than hidden at the ends of the track, so the control does not
   move about under the cursor and the reader can see there is no more that way. */
.rail-btn:disabled { opacity: .38; cursor: default; }
.rail-chev { font-size: 1.05rem; line-height: 1; }

/* The rail. A grid of fixed width columns that scrolls sideways and snaps.
   ⚠️ grid-auto-flow: column with an explicit width is what makes it a rail:
   .cards on its own is a three column grid that wraps, and inheriting that here
   would produce a stack that never scrolls. */
/* ⚠️ .cards.cards--rail, NOT .cards--rail. Two classes deliberately.
   The base .cards block is defined ~1400 lines FURTHER DOWN this stylesheet, so
   at equal specificity it wins on order and quietly reimposed its own grid here:
   the gap came out 44px instead of 34px and, worse, see the template reset
   below. Do not simplify this selector back to one class. */
.cards.cards--rail {
  display: grid; grid-auto-flow: column;
  /* ⚠️ RESET THE EXPLICIT TEMPLATE. .cards sets grid-template-columns:
     repeat(3, 1fr), and an explicit template still defines the first three
     tracks no matter what grid-auto-columns says, so the rail rendered as
     "70px 70px 70px 320px 320px 320px": three collapsed 1fr columns followed by
     the auto ones. grid-auto-columns only governs tracks the template does not.
     The media queries at 1000px and 620px reimpose 2 and 1 columns, and they
     are single class so this selector outranks them there too. */
  grid-template-columns: none;
  /* ⚠️ NOT minmax(0, 320px), WHICH WAS TRIED FIRST AND COLLAPSED THE RAIL.
     A 0 minimum lets the columns shrink to fit the container, so six cards
     rendered 70px wide inside 1136px, the track never overflowed, and the
     arrows correctly hid themselves over what was now a squashed static grid.
     A real minimum is what forces the overflow the carousel is built on.
     clamp keeps it responsive without ever going back below that floor. */
  grid-auto-columns: clamp(260px, 27vw, 320px);
  gap: 34px; overflow-x: auto;
  /* ⚠️ proximity, NOT mandatory. Mandatory SILENTLY CANCELS a smooth
     programmatic scroll: the snap engine aborts the animation and returns to
     the nearest snap point, so scrollBy({behavior:'smooth'}) left the rail
     exactly where it started and BOTH ARROWS DID NOTHING, with no console
     error. Measured: smooth stayed at 4px, auto moved the full 954px.
     Proximity keeps the alignment without fighting the animation. It is also
     the kinder default, because mandatory can trap a reader mid-scroll. */
  /* proximity, not mandatory. Mandatory can trap a reader mid-scroll, and the
     alignment benefit here is the same either way. */
  scroll-snap-type: x proximity;
  /* No scroll-behavior declared on purpose: the arrows pass their own
     behaviour to scrollBy so they can honour prefers-reduced-motion per call,
     and a blanket smooth here would override that choice. */
  /* Room for the focus ring and the card's hover lift, which a clipped
     overflow context would otherwise shave off the top and bottom. */
  padding: 4px 4px 22px;
  margin-inline: -4px;
  scrollbar-width: thin;
}
.cards.cards--rail > .card { scroll-snap-align: start; }
.cards.cards--rail:focus-visible { outline: 2px solid var(--green-700); outline-offset: 4px; }

/* The way through to the rest of the advice. Sits clear of the rail so it reads
   as the next step rather than a card that lost its picture. */
.journal-more { margin-top: 40px; }

footer { background: var(--green-900); color: var(--white); padding: 120px 0 64px; }
footer .cols { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 48px; }
/* ⚠️ .foot-h, not the h4 tag. The footer headings became h2 on 2026-09-06 to
   stop every page skipping a heading level; the class keeps them looking
   identical. Do not put the tag selector back. */
footer .foot-h {
  font-size: .8125rem; font-weight: 900; letter-spacing: .12em;
  text-transform: uppercase; color: var(--green-400); margin: 0 0 20px;
}
footer ul { list-style: none; margin: 0; padding: 0; }
footer li { margin-bottom: 12px; }
footer a { color: rgba(255,255,255,.86); text-decoration: none; }
footer a:hover { color: var(--white); text-decoration: underline; text-underline-offset: 4px; }
footer .values { display: flex; flex-wrap: wrap; gap: 10px 34px; margin-top: 18px; color: rgba(255,255,255,.86); }
footer .brand img { height: 54px; width: auto; }
footer .base {
  margin-top: 84px; padding-top: 30px; border-top: 1px solid rgba(255,255,255,.18);
  display: flex; flex-wrap: wrap; gap: 18px; justify-content: space-between;
  color: rgba(255,255,255,.6); font-size: .875rem;
}

@media (max-width: 1180px) {
  nav { gap: 20px; }
  .navtop { font-size: .875rem; }
}

@media (max-width: 1040px) {
  nav { display: none; }
  .menu-toggle {
    display: inline-flex; background: transparent; border: 1px solid rgba(255,255,255,.5);
    color: var(--white); border-radius: var(--r-sm); padding: 10px 16px;
    font: inherit; font-size: .9375rem; font-weight: 700;
  }
  header.stuck .menu-toggle { border-color: var(--ink-200); color: var(--ink-900); }
  .standard li { grid-template-columns: 1fr; gap: 14px; }
  /* The rail keeps its own scroll on narrow screens, so there is nothing to
     restack. Cards narrow instead, and the last one is left deliberately part
     visible so it is obvious the strip continues. (The old .journal a rule that
     lived here went with the reading list on 2026-09-04.) */
  .cards.cards--rail { grid-auto-columns: 78vw; gap: 20px; }
  .journal-head { margin-bottom: 32px; }
  /* minmax(0,1fr) rather than 1fr. A bare 1fr floors at the content's own
     min-width, and the first column holds the logo and the four value words,
     so it was taking 170px of a 326px row and leaving the link column 108px.
     Measured 2026-09-03. */
  footer .cols { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 40px 32px; }
}

/* One column on a phone. Two columns of about 110px was wrapping "Why use an
   approved agent" onto three lines, which is the sort of thing that reads as a
   broken page rather than a narrow one. Found by measuring the footer at 390px,
   not by looking at it. */
@media (max-width: 620px) {
  footer { padding: 80px 0 56px; }
  footer .cols { grid-template-columns: 1fr; gap: 40px; }
  footer .base { margin-top: 56px; }
}

@media (max-width: 600px) {
  header { padding-left: 16px; padding-right: 16px; gap: 10px; }
  header .mark img { height: 30px; }
  header .cta { padding: 11px 15px; font-size: .875rem; }
  .menu-toggle { padding: 9px 12px; font-size: .875rem; }
  .scroll-hint { display: none; }
}

/* FRONT DOOR, homepage composition (variant A, Cinematic)
   The Ocean Cleanup answer. Impact comes from pacing and reveal.
   Full screens are held, content arrives as you reach it, and the proof
   sequence pins one photograph while three figures advance across it.
   No parallax, no scroll jacking. The scroll never changes speed. */

.hero { align-items: flex-end; }
.hero .inner { padding: 0 34px 96px; max-width: 1180px; }
.hero h1 { color: var(--white); max-width: 14ch; font-size: clamp(3rem, 8vw, 7rem); }
.hero p {
  margin-top: 28px; max-width: 44ch; color: rgba(255,255,255,.92);
  font-size: clamp(1.125rem, 1.6vw, 1.375rem); line-height: 1.45;
}
.hero .actions { margin-top: 42px; display: flex; flex-wrap: wrap; gap: 14px; }

/* HERO, September 2026 revision, from Nick's supplied canvas design (2a).
   The same full bleed photography, but the composition centred: hashtag,
   headline with its closing phrase in pale green, one short paragraph, then
   a green pill beside a plain underlined link. The headline runs at natural
   width rather than condensed because that is how the approved canvas
   renders it; the rest of the site keeps the condensed signature. */
.hero--centred { align-items: center; }
.hero--centred .inner {
  margin-inline: auto; max-width: 900px; text-align: center;
  padding: 150px 34px 96px;
  display: flex; flex-direction: column; align-items: center;
}
.hero--centred .hero-tag {
  margin: 0 0 20px; max-width: none;
  font-size: .8125rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--green-300);
}
.hero--centred h1 {
  /* 21ch clears the longest deliberate line, "Find an estate agent",
     so the <br> is the only break the headline takes on a desktop. */
  font-stretch: 100%; max-width: 21ch;
  font-size: clamp(2.625rem, 5.8vw, 3.875rem);
}
.hero--centred h1 .accent { color: var(--green-300); }
.hero--centred .inner > p:not(.hero-tag) { margin-top: 24px; max-width: 46ch; color: rgba(255,255,255,.85); line-height: 1.6; font-size: clamp(1.0625rem, 1.4vw, 1.1875rem); }
.hero--centred .actions { margin-top: 34px; justify-content: center; align-items: center; gap: 14px 28px; }
.hero--centred .actions .tlink { color: var(--white); }
@media (max-width: 640px) {
  .hero--centred h1 br { display: none; }
}

/* The 2a scrim. Top-heavy rather than directional: the copy now sits in the
   upper half of the frame, so the gradient is deepest behind it and eases off
   towards the pavement, leaving the photograph readable at the foot. White
   copy over the .82 to .94 band measures far past AA; nothing textual sits
   in the .55 band at the bottom. */
.scrim-hero {
  background: linear-gradient(180deg,
    rgba(14,62,34,.94) 0%, rgba(14,62,34,.82) 55%, rgba(14,62,34,.55) 100%);
}

/* One statement, alone on warm paper. The pause between two photographs. */
.statement { min-height: 92svh; display: grid; place-items: center; padding: 130px 34px; background: var(--paper); }
.statement .inner { max-width: 940px; }
.statement h2 { font-size: clamp(2.25rem, 5.6vw, 5.25rem); }
.statement .green { color: var(--green-700); }
.statement p { margin-top: 36px; max-width: 46ch; color: var(--ink-600); font-size: 1.25rem; }

/* THE PINNED PROOF SEQUENCE.
   A tall track holds a photograph still while three figures cross through it.
   The page scrolls at its normal speed throughout: only the content inside
   the pinned frame changes, which is reveal rather than scroll jacking. */
/* Height scales with however many figures the Customizer is publishing.
   A custom property rather than an inline style, so the reduced-motion rule
   below can still unpin the whole thing. An inline height would beat it. */
.track {
  position: relative;
  height: calc((var(--track-steps, 3) + 1) * 80svh);
  background: var(--green-900);
}
.track .pin { position: sticky; top: 0; height: 100svh; overflow: hidden; }
.track .pin > img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: .34;
}
.track .pin > .wash { position: absolute; inset: 0; background: rgba(14,62,34,.72); }
.track .stage { position: relative; height: 100%; display: grid; place-items: center; text-align: center; padding: 0 34px; }
.track .step {
  position: absolute; max-width: 900px;
  opacity: 0; transform: translateY(26px);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
  pointer-events: none;
}
.track .step.on { opacity: 1; transform: none; }
.track .fig {
  font-stretch: 75%; font-weight: 800; letter-spacing: -.04em; line-height: .82;
  font-size: clamp(6rem, 20vw, 17rem); color: var(--white);
}
.track .said {
  margin-top: 22px; font-stretch: 75%; font-weight: 800; letter-spacing: -.02em;
  font-size: clamp(1.5rem, 3.2vw, 3rem); line-height: 1.1; color: var(--white);
  max-width: 22ch; margin-inline: auto;
}
.track .because { margin-top: 26px; max-width: 46ch; margin-inline: auto; color: rgba(255,255,255,.8); font-size: 1.125rem; }

/* Progress rail. Tells you where you are in the sequence, three quiet ticks. */
.track .rail { position: absolute; left: 50%; bottom: 54px; transform: translateX(-50%); display: flex; gap: 10px; }
.track .rail i { display: block; width: 34px; height: 3px; background: rgba(255,255,255,.28); border-radius: var(--r-pill); transition: background var(--dur) var(--ease); }
.track .rail i.on { background: var(--green-400); }

/* Bright sunlit grass sits exactly where this plate's body copy lands, and
   body copy needs 4.5:1 rather than the 3:1 a headline gets. Deepen this one. */
.scrim-deep {
  background:
    linear-gradient(to right,
      rgba(17,17,17,.86) 0%, rgba(17,17,17,.70) 28%,
      rgba(17,17,17,.34) 54%, rgba(17,17,17,0) 76%),
    linear-gradient(to top,
      rgba(17,17,17,.74) 0%, rgba(17,17,17,.30) 48%, rgba(17,17,17,0) 80%);
}

/* A held photograph carrying one line. */
.plate .inner { align-self: flex-end; padding: 0 34px 84px; max-width: 940px; }
.plate h2 { color: var(--white); }
.plate p { margin-top: 24px; max-width: 42ch; color: rgba(255,255,255,.9); }

@media (max-width: 940px) {
  .track { height: calc((var(--track-steps, 3) + 1) * 75svh); }
}
@media (prefers-reduced-motion: reduce) {
  /* No pin, no sequence. The three figures simply stack and read as a list. */
  .track { height: auto; }
  .track .pin { position: static; height: auto; padding: 90px 0; }
  .track .stage { display: grid; gap: 80px; padding: 0 34px; }
  .track .step { position: static; opacity: 1; transform: none; }
  .track .rail { display: none; }
}

/* HELD STILL, 2026-09-03. Dan's review: the pinned frame read as the bottom of
   the page and took two or three scrolls to clear, so a browsing visitor stops
   there thinking the page has ended. Same rules as the reduced-motion branch
   above, applied to everybody, which is why they are duplicated rather than
   shared: that branch is a user preference and this is an editorial decision,
   and the two should be able to change independently. Drop track--still in
   front-page.php to restore the pinned sequence. */
.track--still { height: auto; }
.track--still .pin { position: static; height: auto; padding: 90px 0; }
.track--still .stage { display: grid; gap: 80px; padding: 0 34px; }
.track--still .step { position: static; opacity: 1; transform: none; }
.track--still .rail { display: none; }

/* ---------------------------------------------------------------
   Interior pages. The homepage is front door mode; everything else
   is plain and fast, per the two mode rule.
   --------------------------------------------------------------- */

.page-head { padding: 190px 0 70px; background: var(--paper); }
.page-head h1 { max-width: 18ch; }
.page-head .lede { margin-top: 26px; max-width: 46ch; color: var(--ink-600); }
/* Buttons under a page head. Added 2026-09-04 for the 404, which previously
   carried this spacing as an inline style on the paragraph; .dp-actions brings
   the flex row with it so the three buttons wrap on a narrow screen instead of
   overflowing. Scoped to .page-head so no other .dp-actions is affected. */
.page-head .dp-actions { margin-top: 32px; }

.article { padding: 20px 0 110px; background: var(--paper); }
.article .byline { margin-top: 20px; color: var(--ink-500); font-size: .9375rem; font-weight: 600; }
.article-image { margin: 54px 0; }
/* ⚠️ max-width, NOT width. The theme's own article images are 1500px or wider and
   filled the column happily. The 193 posts migrated from the old site carry
   featured images that are only 750x500, and `width: 100%` stretched every one of
   them well past its natural size: soft, oversized, and visibly wrong. max-width
   lets a small image sit at its real size and still caps a large one. */
.article-image img { max-width: 100%; height: auto; display: block; margin-inline: auto; border-radius: var(--r-lg); }

.entry { padding-top: 14px; }
.entry h2 { margin: 54px 0 18px; font-size: clamp(1.75rem, 3vw, 2.5rem); }
.entry h3 { margin: 40px 0 14px; }
.entry p, .entry li { font-size: 1.1875rem; line-height: 1.62; color: var(--ink-700); }
.entry ul, .entry ol { padding-left: 1.3em; margin: 0 0 1.1em; }
.entry li { margin-bottom: .5em; }
.entry a { color: var(--green-800); text-decoration: underline; text-underline-offset: 4px; }
.entry blockquote {
  margin: 40px 0; padding-left: 26px; border-left: 2px solid var(--green-700);
  font-family: 'Source Serif 4', Georgia, serif; font-style: italic;
  font-size: clamp(1.25rem, 2vw, 1.625rem); line-height: 1.45; color: var(--ink-700);
}
.entry img { max-width: 100%; height: auto; border-radius: var(--r-md); }

/* Nick, 2026-08-12: "at the bottom you've got the pages, but it's all cramped
   together." It was: a 10px gap between 32px targets, hard against the last
   row of content. */
.pager { margin-top: 72px; padding-top: 40px; border-top: 1px solid var(--ink-200); }
.pager .nav-links { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.pager .page-numbers {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 46px; height: 46px; padding: 0 14px;
  border: 1px solid var(--ink-200); border-radius: var(--r-sm);
  color: var(--ink-700); text-decoration: none; font-weight: 700;
}
.pager .page-numbers:hover { background: var(--green-050); }
.pager .page-numbers.current { background: var(--green-700); border-color: var(--green-700); color: var(--white); }

/* Interior pages have no hero, so the header is solid from the first pixel
   and its content needs the ink colours rather than the over-photo whites. */
.no-hero header { background: var(--paper); border-bottom-color: var(--ink-200); }
.no-hero header::before { opacity: 0; }
.no-hero nav a { color: var(--ink-700); }
.no-hero nav a[aria-current="page"], .no-hero nav .agent-link { color: var(--green-700); border-bottom-color: var(--green-700); }
.no-hero header .cta { background: var(--green-700); color: var(--white); }
.no-hero header .cta:hover { background: var(--green-800); }
.no-hero .menu-toggle { border-color: var(--ink-200); color: var(--ink-900); }

/* WordPress admin bar must not sit on top of the fixed header. */
.admin-bar header { top: 32px; }
@media screen and (max-width: 782px) { .admin-bar header { top: 46px; } }

/* ---------------------------------------------------------------
   The booking form. Directory mode: plain, fast, one job.
   Labels are always words. Nothing here relies on a placeholder to
   say what a field is, because a placeholder disappears the moment
   somebody starts typing.
   --------------------------------------------------------------- */

.booking-section { padding: 10px 0 120px; background: var(--paper); }

.booking { display: grid; grid-template-columns: 1fr 1fr; gap: 26px 24px; }
.booking .field-wide { grid-column: 1 / -1; }
.booking label {
  display: block; font-weight: 700; font-size: 1rem;
  color: var(--ink-900); margin-bottom: 8px;
}
.booking .optional { font-weight: 400; color: var(--ink-500); margin-left: 6px; }
.booking .hint { margin: -2px 0 10px; font-size: .9375rem; line-height: 1.45; color: var(--ink-500); }

.booking input,
.booking select,
.booking textarea {
  width: 100%; font: inherit; font-size: 1.0625rem;
  padding: 14px 15px; color: var(--ink-900); background: var(--white);
  border: 1px solid var(--ink-200); border-radius: var(--r-md);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.booking textarea { resize: vertical; min-height: 150px; line-height: 1.55; }
.booking select { appearance: none; padding-right: 42px; background-image: none; }
.booking input:hover, .booking select:hover, .booking textarea:hover { border-color: var(--ink-300); }
.booking input:focus-visible,
.booking select:focus-visible,
.booking textarea:focus-visible { border-color: var(--green-500); }

.booking .submit { margin-top: 10px; }
.booking .submit .note { margin-top: 18px; max-width: 52ch; font-size: .9375rem; line-height: 1.5; color: var(--ink-500); }
.booking .submit .note a { color: var(--green-800); text-decoration: underline; text-underline-offset: 3px; }

.form-result {
  padding: 40px 38px; background: var(--green-050);
  border: 1px solid var(--green-200); border-radius: var(--r-md);
}
.form-result h2 { font-size: clamp(1.5rem, 2.6vw, 2.25rem); margin-bottom: 18px; }
.form-result p { color: var(--ink-700); max-width: 54ch; }

.form-error {
  margin-bottom: 30px; padding: 18px 20px;
  background: #FBEDEB; border: 1px solid var(--danger); border-radius: var(--r-md);
  color: #7A241B; font-size: 1rem; line-height: 1.5;
}
.form-error strong { display: block; margin-bottom: 3px; }

/*
 * What a form promises before it is filled in.
 *
 * On the contact page this carries the two answers a complainant needs: that
 * nothing reaches the agency without her say so, and that a person replies
 * within three working days. Calm, not alarming: this is reassurance, so it
 * takes the green wash the thank you state uses and never the error red.
 * Council Audit critical 4.
 */
.form-notice {
  margin-bottom: 30px; padding: 20px 22px;
  background: var(--green-050); border: 1px solid var(--green-200);
  border-radius: var(--r-md);
}
.form-notice p { color: var(--ink-800); font-size: 1rem; line-height: 1.55; max-width: 62ch; }
.form-notice p + p { margin-top: 10px; }

/*
 * A field that came back wrong, on the contact and application forms.
 *
 * ⚠️ SAME CLASSES AS THE FUNNEL, DELIBERATELY: .field--bad on the wrapper and
 * .field-error on the message, both defined further down with the funnel. Two
 * parallel error conventions in one stylesheet is how one of them drifts.
 *
 * The error block above used to say "check the fields marked as needed" on a
 * page where nothing was marked and every box had been emptied. inc/form.php
 * now redraws the form filled in and flags what failed, and these are the marks
 * it was talking about. Council Audit finding 8.
 *
 * Colour is never the only signal: the message is words, above the field, and
 * the input carries aria-invalid for anything not reading the page.
 */
.field--bad > label { color: #a4231f; }
.field--bad input:focus,
.field--bad select:focus,
.field--bad textarea:focus { box-shadow: 0 0 0 3px rgba(164, 35, 31, .14); }


@media (max-width: 1000px) {
}
@media (max-width: 640px) {
  .booking { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------
   Interior page blocks: directory, contact, people, promises, pricing.
   --------------------------------------------------------------- */

.directory { padding: 10px 0 120px; background: var(--paper); }
.directory-intro { max-width: 62ch; margin-bottom: 56px; }
.directory-intro p { color: var(--ink-600); font-size: 1.125rem; line-height: 1.6; }
.directory-intro strong { color: var(--ink-900); }
.directory-intro .btn { margin-top: 22px; }

.member-list { list-style: none; margin: 0; padding: 0; columns: 3; column-gap: 48px; }
.member-list li { break-inside: avoid; padding: 14px 0; border-top: 1px solid var(--ink-200); }
.member-name { display: block; font-weight: 700; font-size: 1.0625rem; }
.member-area { display: block; margin-top: 2px; font-size: .9375rem; color: var(--ink-500); }

.directory-note { margin-top: 76px; padding-top: 46px; border-top: 1px solid var(--ink-200); max-width: 62ch; }
.directory-note h2 { margin-bottom: 16px; }
.directory-note p { color: var(--ink-600); margin-bottom: 24px; }

.contact { padding: 10px 0 120px; background: var(--paper); }
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; margin-bottom: 72px; }
.contact-grid h2 { font-size: clamp(1.375rem, 2.2vw, 1.875rem); margin-bottom: 14px; }
.contact-grid p { color: var(--ink-600); margin-bottom: 22px; max-width: 42ch; }

.contact-list { list-style: none; margin: 0; padding: 0; max-width: 620px; }
.contact-list li {
  display: flex; flex-wrap: wrap; gap: 8px 24px; align-items: baseline;
  padding: 20px 0; border-top: 1px solid var(--ink-200);
}
.contact-list li:last-child { border-bottom: 1px solid var(--ink-200); }
.contact-label { min-width: 130px; color: var(--ink-500); font-size: .9375rem; font-weight: 600; }
.contact-list a {
  font-stretch: 75%; font-weight: 800; font-size: clamp(1.125rem, 1.8vw, 1.5rem);
  letter-spacing: -.01em; color: var(--green-800);
  text-decoration: underline; text-underline-offset: 4px;
}

.team { padding: 10px 0 110px; background: var(--paper); }
.team .lede { max-width: 52ch; color: var(--ink-600); margin: 18px 0 46px; }
.people { list-style: none; margin: 0; padding: 0; columns: 2; column-gap: 62px; }
.people li { break-inside: avoid; padding: 20px 0; border-top: 1px solid var(--ink-200); }
.person-name { display: block; font-stretch: 75%; font-weight: 800; font-size: 1.25rem; letter-spacing: -.01em; }
.person-role { display: block; margin-top: 5px; color: var(--ink-600); font-size: 1rem; line-height: 1.5; }

.promise-block { padding: 110px 0; background: var(--green-900); color: var(--white); }
.promise-block h2 { color: var(--white); max-width: 15ch; margin-bottom: 48px; }
.promises { list-style: none; counter-reset: pr; margin: 0; padding: 0; columns: 2; column-gap: 62px; }
.promises li {
  counter-increment: pr; break-inside: avoid;
  display: grid; grid-template-columns: 40px 1fr; gap: 16px;
  padding: 20px 0; border-top: 1px solid rgba(255,255,255,.16);
  font-size: 1.0625rem; line-height: 1.5;
}
.promises li::before {
  content: counter(pr); font-stretch: 75%; font-weight: 800;
  font-size: 1.125rem; color: var(--green-400); line-height: 1.5;
}

.pricing { padding: 110px 0; background: var(--paper); }
.pricing .inner { max-width: 56ch; }
.pricing .price {
  margin: 24px 0 20px; font-stretch: 75%; font-weight: 800;
  font-size: clamp(3.5rem, 8vw, 6rem); line-height: 1; letter-spacing: -.03em;
  color: var(--green-700);
}
.pricing .price span {
  display: block; margin-top: 10px; font-size: 1.125rem;
  font-stretch: 100%; font-weight: 600; letter-spacing: 0; color: var(--ink-600);
}
.pricing p { color: var(--ink-600); }
.pricing .note { margin-top: 20px; font-size: .9375rem; color: var(--ink-500); }

@media (max-width: 1000px) {
  .member-list { columns: 2; }
}
@media (max-width: 720px) {
  .member-list, .people, .promises { columns: 1; }
  .contact-grid { grid-template-columns: 1fr; gap: 44px; }
}

/* ---------------------------------------------------------------
   The Promise, and the seven point checklist.
   Both are single-idea pages. Nothing competes with the list.
   --------------------------------------------------------------- */

/* The eight promises, rebuilt 2026-08-12.
   These are the most important sentences on the site. The old treatment set
   "We promise to" as a small grey label above every line and left the actual
   words smaller than the label, so eight commitments read as eight list items.
   Now the sentence is the largest thing in the row and the number gets out of
   its way. */
.promise-page { padding: 10px 0 90px; background: var(--paper); }
.promise-full { list-style: none; margin: 0; padding: 0; }
.promise-full li {
  display: grid; grid-template-columns: 74px minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 0 40px;
  padding: 34px 0; border-top: 1px solid var(--ink-200);
}
.promise-full li:last-child { border-bottom: 1px solid var(--ink-200); }
.promise-num {
  font-stretch: 75%; font-weight: 800; letter-spacing: -.02em;
  font-size: 1.25rem; line-height: 1.35; color: var(--green-500);
  padding-top: .18em;
}
.promise-body {
  font-stretch: 75%; font-weight: 800; letter-spacing: -.015em;
  font-size: clamp(1.25rem, 2.5vw, 1.875rem); line-height: 1.22;
  color: var(--ink-900); max-width: 26ch;
}
.promise-cost {
  grid-column: 3; display: block; margin-top: .35em;
  color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6; max-width: 46ch;
}

.promise-close { padding: 20px 0 120px; background: var(--paper); }
.promise-close h2 { margin-bottom: 18px; }
.promise-actions { display: flex; flex-wrap: wrap; gap: 18px 28px; align-items: center; margin-top: 34px; }
.promise-actions .tlink { color: var(--green-800); }

@media (max-width: 900px) {
  .promise-full li { grid-template-columns: 74px minmax(0, 1fr); gap: 0 8px; }
  .promise-cost { grid-column: 2; margin-top: 14px; max-width: 56ch; }
}
@media (max-width: 640px) {
  .promise-full li { grid-template-columns: 1fr; gap: 8px; padding: 26px 0; }
  .promise-num { font-size: 1rem; }
  .promise-cost { grid-column: 1; }
}

.checklist-page { padding: 10px 0 120px; background: var(--paper); }
.checks { list-style: none; counter-reset: ck; margin: 0; padding: 0; max-width: 900px; }
.checks li {
  counter-increment: ck;
  display: grid; grid-template-columns: 74px 1fr; gap: 26px;
  padding: 34px 0; border-top: 1px solid var(--ink-200);
}
.checks li:last-child { border-bottom: 1px solid var(--ink-200); }
.checks li::before {
  content: counter(ck);
  font-stretch: 75%; font-weight: 800; font-size: 2.25rem;
  color: var(--green-700); line-height: .9;
}
.checks h2 { font-size: clamp(1.25rem, 2vw, 1.625rem); margin-bottom: 10px; }
.checks p { color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6; max-width: 58ch; margin: 0; }
.checklist-after { margin-top: 64px; padding-top: 40px; border-top: 1px solid var(--ink-200); max-width: 58ch; }
.checklist-after h2 { margin-bottom: 16px; }
.checklist-after p { color: var(--ink-600); font-size: 1.125rem; margin-bottom: 26px; }

@media (max-width: 640px) {
  .promise-full li, .checks li { grid-template-columns: 48px 1fr; gap: 16px; }
  .promise-full li::before { font-size: 1.25rem; }
  .checks li::before { font-size: 1.625rem; }
}

/* ---------------------------------------------------------------
   For agents: the itemised value, and the two named benefits.
   --------------------------------------------------------------- */

.value { padding: 10px 0 100px; background: var(--paper); }
.value .lede { max-width: 50ch; color: var(--ink-600); margin: 16px 0 48px; }
.value-list { list-style: none; margin: 0; padding: 0; max-width: 880px; }
.value-list li {
  display: flex; flex-wrap: wrap; gap: 12px 32px; align-items: baseline;
  justify-content: space-between; padding: 26px 0; border-top: 1px solid var(--ink-200);
}
.value-what { flex: 1 1 380px; }
.value-title { display: block; font-weight: 800; font-size: 1.125rem; }
.value-note { display: block; margin-top: 4px; color: var(--ink-500); font-size: .9375rem; line-height: 1.5; }
.value-figure {
  font-stretch: 75%; font-weight: 800; letter-spacing: -.02em;
  font-size: clamp(1.75rem, 3vw, 2.5rem); color: var(--ink-900); line-height: 1;
}
.value-total {
  display: flex; flex-wrap: wrap; gap: 12px 32px; align-items: baseline; justify-content: space-between;
  max-width: 880px; margin-top: 8px; padding: 34px 0 0; border-top: 2px solid var(--ink-900);
}
.value-total-label { font-weight: 800; font-size: 1.125rem; }
.value-total-figure {
  font-stretch: 75%; font-weight: 800; letter-spacing: -.03em; line-height: 1;
  font-size: clamp(3rem, 6.5vw, 5rem); color: var(--green-700);
}
.value-more { max-width: 56ch; margin-top: 30px; color: var(--ink-600); }

.benefits { padding: 100px 0; background: var(--green-900); color: var(--white); }
.benefits .wrap { display: grid; grid-template-columns: 1fr 1fr; gap: 62px; }
.benefit h2 { color: var(--white); font-size: clamp(1.5rem, 2.6vw, 2.25rem); max-width: 18ch; }
.benefit p { margin-top: 20px; color: rgba(255,255,255,.82); line-height: 1.6; }

@media (max-width: 860px) {
  .benefits .wrap { grid-template-columns: 1fr; gap: 44px; }
  .value-list li, .value-total { flex-direction: column; align-items: flex-start; gap: 10px; }
}

/* An empty section says why it is empty rather than showing nothing. */
.empty-note { max-width: 56ch; padding: 46px 0 10px; }
.empty-note h2 { margin-bottom: 16px; }
.empty-note p { color: var(--ink-600); font-size: 1.125rem; line-height: 1.6; margin-bottom: 26px; }

.karma-stories { border-top: 1px solid var(--ink-200); padding-top: 90px; }
.karma-stories h2 { max-width: 16ch; }

.archive-link { padding: 90px 0; background: var(--paper); border-top: 1px solid var(--ink-200); }
.archive-link .inner { display: flex; flex-wrap: wrap; gap: 40px; align-items: center; justify-content: space-between; }
.archive-link h3 { max-width: 18ch; }
.archive-link p { margin-top: 14px; color: var(--ink-600); max-width: 46ch; }

/* ---------------------------------------------------------------
   HOMEPAGE, rebuilt for a nervous seller.
   The blocks below carry the guidance sections. Four of them are lists
   one after another, so each one deliberately has a different silhouette:
   a wide numbered sequence on green, a narrow numbered list on paper,
   two columns of questions, and a short centred block.
   --------------------------------------------------------------- */

/* The sale map. Reuses .promise-block and .promises, single column and wider,
   because these are seven steps in an order rather than eight equal statements
   and the bodies are far longer than a promise. */
.promise-block .lede { max-width: 54ch; margin: 22px 0 0; color: rgba(255,255,255,.8); font-size: 1.125rem; }
.promise-block .after { margin-top: 44px; max-width: 54ch; color: rgba(255,255,255,.8); }
.promise-block--sale h2 { max-width: 20ch; margin-bottom: 0; }
.promise-block--sale .promises { columns: 1; max-width: 880px; margin-top: 58px; }
.promise-block--sale .promises li { align-items: baseline; padding: 26px 0; }
.promise-block--sale .promises strong {
  display: block; margin-bottom: 6px;
  font-stretch: 75%; font-weight: 800; letter-spacing: -.01em;
  font-size: 1.1875rem; line-height: 1.2;
}
.promise-block--sale .promises span { color: rgba(255,255,255,.82); }

/* The statement carries two paragraphs here rather than one, the second of
   which is the plain definition sentence. */
.statement--wide p { max-width: 54ch; }
.statement--wide p + p { margin-top: 22px; font-size: 1.125rem; color: var(--ink-700); }

/* Plates carrying a full paragraph rather than a single line. */
.plate--long p { max-width: 54ch; }
.plate .links { margin-top: 26px; display: flex; flex-wrap: wrap; gap: 12px 28px; }
.plate .links a { color: var(--white); }

/* The eight questions. Same running list as the entry standard, but the
   question is the heading so it needs more room than a three word label. */
.standard--ask li h3 { font-size: clamp(1.25rem, 2.2vw, 1.75rem); max-width: 26ch; }
.standard--ask .after {
  margin-top: 56px; padding-top: 32px; border-top: 1px solid var(--ink-200);
  max-width: 64ch; color: var(--ink-600);
}
.standard--ask .after a { color: var(--green-800); }

/* A persistent heading over the pinned sequence. The component shipped with no
   heading at all, which is why it was invisible in the document outline.
   Absolute so the three figures keep centring themselves beneath it. */
/* The frame is pinned under a fixed header, so the heading has to clear the
   header's own height rather than the top of the viewport. */
.track .stage { padding: 168px 34px 96px; }
.track .stage > h2 {
  position: absolute; top: 116px; left: 34px; right: 34px;
  margin: 0; text-align: center; color: rgba(255,255,255,.86);
  font-size: clamp(1.25rem, 2.4vw, 1.875rem);
}

/* The questions people actually ask. Visible text, never an accordion. */
.faq { padding: 120px 0 130px; background: var(--paper); border-top: 1px solid var(--ink-200); }
.faq h2 { max-width: 18ch; }
.faq .qa { margin-top: 62px; columns: 2; column-gap: 62px; }
.faq .qa > div { break-inside: avoid; padding: 24px 0; border-top: 1px solid var(--ink-200); }
.faq h3 { font-size: clamp(1.125rem, 1.8vw, 1.375rem); margin-bottom: 10px; max-width: 30ch; }
.faq p { color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6; margin: 0; max-width: 58ch; }

/* The escape hatch. Small and plain on purpose, and placed before the ask
   rather than after it. */
/* The escape hatch. A held photograph rather than a fourth paper block, because
   the run of FAQ, escape and close was reading as a wall of type. It is also the
   only thing on the page that can cost the network money, which is exactly why
   the rest of the page is believable, so it earns a screen of its own. */
.escape.plate .inner { align-self: flex-end; padding-bottom: 96px; }

/* The badge plate. The photograph is portrait and the stickers sit centre
   right, so the frame is anchored to the right and the type block is capped
   short of them. Widening this past 46ch walks the headline over the thing the
   section exists to show. */
/* ⚠️ X IS INERT HERE AND THAT IS NOT A MISTAKE. The plate is wider than the
   photograph's own ratio (1.84 against 1.50), so `cover` fills the width and
   crops vertically only. Y is the single lever. Chasing the composition
   sideways with X wastes an hour: measured 2026-09-03. */
.plate--badge > img.bg { object-position: 50% 50%; }
.plate--badge .inner { align-self: flex-end; padding-bottom: 96px; }
/* 38ch, not 46. At 46 the second line of the headline reached under the badge
   and the section was covering the one thing it exists to show. Measured, not
   guessed: widen this and check the headline's right edge against the disc. */
.plate--badge .inner > div { max-width: 38ch; }
.plate--badge p { margin-top: 20px; color: rgba(255,255,255,.92); font-size: 1.125rem; line-height: 1.6; }
/* ⚠️ AN EXTRA BOTTOM GRADIENT, AND IT IS LOAD BEARING. The agency's printed
   literature is white and it runs along the bottom left, which is exactly where
   the closing link sits. scrim-anchor alone left that link on near white paper.
   This is the same fix the hero already carries for sunlit pavement. */
.plate--badge .scrim-anchor {
  background:
    linear-gradient(to right,
      rgba(17,17,17,.94) 0%, rgba(17,17,17,.88) 30%,
      rgba(17,17,17,.48) 50%, rgba(17,17,17,.08) 70%, rgba(17,17,17,0) 84%),
    linear-gradient(to top,
      rgba(17,17,17,.62) 0%, rgba(17,17,17,.22) 30%, rgba(17,17,17,0) 62%),
    /* ⚠️ A CORNER LAYER, AND IT IS NOT DECORATION. The agency's white printed
       literature runs diagonally across the bottom left, which is precisely
       where the closing link sits, and a straight bottom gradient strong enough
       to fix it also veiled the badge on the right. This is weighted into the
       corner only. Anything added here must be checked against the link, not
       against the headline: the headline sits higher, on the dark half, and was
       never the one at risk. */
    linear-gradient(to top right,
      rgba(17,17,17,.80) 0%, rgba(17,17,17,.42) 22%, rgba(17,17,17,0) 46%);
}
.plate--badge .links a { color: var(--white); }

/* The escape hatch, set as type on paper from 2026-09-03. It inherits
   statement--split, so it only needs the link colour, which on paper has to
   come off the white default the plates use. */
.escape-plain .links { margin-top: 28px; }
.escape-plain .links a { color: var(--green-800); }
@media (max-width: 900px) {
  /* ⚠️ IT STACKS ON A PHONE, IT DOES NOT OVERLAY, AND THAT IS THE THIRD
     ATTEMPT. The photograph is landscape and a phone frame is portrait, so
     `cover` crops it to a giant fragment; at every crop tried, the headline
     landed across the face of the badge, which is the one thing the section
     exists to show. Moving the crop only moved which part of the badge got
     covered.
     So the composition changes rather than the crop: the photograph runs full
     width at its own aspect, and the words sit underneath on the forest ground.
     Same order as the promise-shot figures elsewhere on the site, so it is not
     a new pattern, and nothing overlaps anything. */
  .plate--badge { min-height: 0; display: block; background: var(--green-900); }
  .plate--badge > img.bg {
    position: static; width: 100%; height: auto;
    aspect-ratio: 3 / 2; object-position: 56% 50%;
  }
  .plate--badge > .scrim { display: none; }
  /* ⚠️ padding-block, NOT shorthand. `.inner` here is also the `.wrap`, and a
     shorthand padding resets its side gutter to zero and runs the type to both
     edges. That is the identical fault fixed on About us earlier today, so it
     is clearly an easy one to write twice. */
  .plate--badge .inner { padding-block: 36px 60px; }
  .plate--badge .inner > div { max-width: none; }
  .plate--badge p { color: rgba(255,255,255,.86); }
}
}
.escape.plate .inner > div { max-width: 56ch; }
.escape.plate p { margin-top: 20px; color: rgba(255,255,255,.9); font-size: 1.125rem; line-height: 1.6; }

/* The numbered ".book .steps" list was REMOVED on 2026-09-04, Nick's copy pass.
   It answered the hesitation that "one form means a month of phone calls" in
   three legs; that is now one sentence in the paragraph above the buttons.
   The rules went with it, verified dead first: they were scoped .book .steps,
   ".book" exists only in the homepage booking section, and no class="steps"
   remains anywhere in the theme. Restore from git alongside the $ean_route
   array in front-page.php if the sequence is ever wanted back. */
.book .actions { margin-top: 40px; display: flex; flex-wrap: wrap; gap: 20px 28px; align-items: center; }
.book .actions .tlink { color: var(--white); }

/* Promoted from h3 to h2 so the outline has no skipped level. Kept visually
   subordinate, because it is the one section on the page not written for the
   homeowner. */
.agents h2 { max-width: 18ch; font-size: clamp(1.375rem, 2.4vw, 2rem); }

@media (max-width: 720px) {
  .faq .qa { columns: 1; }
}

@media (prefers-reduced-motion: reduce) {
  /* The sequence unpins and stacks, so its heading rejoins the flow. */
  .track .stage { padding: 0 34px; }
  .track .stage > h2 { position: static; margin-bottom: 8px; text-align: left; }
}

/* The held version needs the same, and it has to be declared down here rather
   than beside the other track--still rules: `.track .stage` is set again at the
   top of this block with equal specificity, so anything earlier loses to it. */
.track--still .stage { padding: 0 34px; }
.track--still .stage > h2 { position: static; margin-bottom: 8px; text-align: center; }

.faq .faq-more { margin: 44px 0 0; padding-top: 30px; border-top: 1px solid var(--ink-200); }
.faq .faq-more a { color: var(--green-800); }

/* A photograph with bright subjects spread across its full width needs more
   than scrim-deep. The member team frame measured 2.55:1 behind the headline,
   which fails even the 3:1 large-text threshold, while the body copy lower down
   passed at 7.98. The difference is height, not side: the to-top layer had
   already faded to almost nothing where the headline sits. This holds the
   darkness higher up the frame and still lets the right third of the picture
   through. */
.scrim-deeper {
  background:
    linear-gradient(to right,
      rgba(17,17,17,.90) 0%, rgba(17,17,17,.80) 32%,
      rgba(17,17,17,.48) 58%, rgba(17,17,17,0) 82%),
    linear-gradient(to top,
      rgba(17,17,17,.88) 0%, rgba(17,17,17,.64) 38%,
      rgba(17,17,17,.18) 68%, rgba(17,17,17,0) 90%);
}

/* The three promises, quoted. A left rule rather than quote marks: the strings
   already carry apostrophes, and quote glyphs get lost in white type over a
   scrimmed photograph. */
.plate .quoted {
  list-style: none; margin: 24px 0 0; padding: 0 0 0 18px;
  border-left: 2px solid rgba(255,255,255,.45);
  max-width: 54ch; display: grid; gap: 12px;
}
.plate .quoted li { color: rgba(255,255,255,.9); line-height: 1.5; }

/* The telephone, in the close. The theme was asserting a number in its
   structured data while the visible page carried none. */
.book .ring { margin-top: 26px; color: rgba(255,255,255,.85); max-width: 52ch; }
.book .ring a {
  color: var(--white); font-size: 1.25rem; font-weight: 700;
  text-decoration: none; border-bottom: 1px solid rgba(255,255,255,.4);
  white-space: nowrap;
}
.book .ring a:hover { border-bottom-color: var(--white); }

/* The agencies, set in type. Reuses .member-list from the directory unchanged. */
.agencies { padding: 110px 0 120px; background: var(--paper); border-top: 1px solid var(--ink-200); }
.agencies h2 { max-width: 14ch; }
.agencies .count {
  margin: 18px 0 46px; font-stretch: 75%; font-weight: 800; letter-spacing: -.01em;
  font-size: clamp(1.125rem, 1.8vw, 1.5rem); color: var(--green-700);
}
.agencies .after { margin-top: 46px; padding-top: 30px; border-top: 1px solid var(--ink-200); max-width: 62ch; }
.agencies .after p { color: var(--ink-600); margin-bottom: 14px; }
.agencies .after a { color: var(--green-800); }

/* Take the eight questions with you. Hidden without script so a blocked script
   never leaves a control that does nothing. */
.ean-print, .print-only { display: none; }
.js .ean-print { display: inline-flex; margin-top: 24px; }
.print-note { display: block; margin-top: 12px; font-size: .9375rem; color: var(--ink-600); max-width: 48ch; }

@media print {
  @page { margin: 14mm; }
  header, footer, main > section:not(#ask),
  .ean-print, .print-note,
  .standard--ask .top p, .standard--ask .after p, .standard--ask .after a { display: none !important; }
  /* Load bearing. Without it a print started from anywhere but a fully scrolled
     section 5 comes out blank, because .js .rv sits at opacity 0. */
  .rv, .js .rv { opacity: 1 !important; transform: none !important; transition: none !important; }
  body { background: #fff; color: #000; }
  .standard { padding: 0; background: #fff; }
  .standard .wrap { max-width: none; padding: 0; }
  .standard--ask h2 { font-size: 16pt; margin: 0 0 10pt; }
  .standard ol { margin: 0; }
  .standard li { grid-template-columns: 22pt 1fr; gap: 10pt; padding: 7pt 0; border-top: 1px solid #ccc; break-inside: avoid; }
  .standard li::before { font-size: 12pt; color: #000; }
  .standard--ask li h3 { font-size: 11.5pt; max-width: none; margin-bottom: 3pt; }
  .standard li p { font-size: 9.5pt; line-height: 1.35; color: #222; max-width: none; }
  .standard--ask .after { margin: 0; padding: 0; border: 0; }
  .print-only { display: block; margin-top: 10pt; font-size: 8pt; color: #444; }
}

/* ---------------------------------------------------------------
   ABOUT US. Interior page, plain and fast, one photographic plate.
   --------------------------------------------------------------- */

/* The register reuses .value and .value-list from For agents unchanged. It
   needs a heading and lede it did not have there, and no total, because there
   is nothing to total. */
.value.register { padding: 96px 0 100px; border-top: 1px solid var(--ink-200); }
.value.register h2 { max-width: 20ch; }
.value.register .lede { margin: 20px 0 46px; }
.value.register .value-more h3 { font-size: clamp(1.25rem, 2vw, 1.625rem); margin-bottom: 14px; }
.value.register .value-more p { margin-bottom: 16px; }
.value.register .value-more p:last-child { margin-bottom: 0; }

/* The four values, each with what it rules out. A running definition list
   rather than four boxes on a grid: a grid says four equal decorations, a list
   says each word costs something. */
.creed-section { padding: 96px 0 110px; background: var(--paper); border-top: 1px solid var(--ink-200); }
.creed-section h2 { max-width: 22ch; }
.creed-section .lede { margin: 20px 0 54px; max-width: 56ch; color: var(--ink-600); font-size: 1.125rem; }
.creed { margin: 0; padding: 0; max-width: 940px; }
.creed > div {
  display: grid; grid-template-columns: 230px 1fr; gap: 26px;
  padding: 32px 0; border-top: 1px solid var(--ink-200);
}
.creed > div:last-child { border-bottom: 1px solid var(--ink-200); }
.creed dt {
  font-stretch: 75%; font-weight: 800; letter-spacing: -.02em; line-height: 1.05;
  font-size: clamp(1.5rem, 2.6vw, 2rem); color: var(--green-700);
}
.creed dd { margin: 0; color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6; max-width: 58ch; }
.creed dd a { color: var(--green-800); text-decoration: underline; text-underline-offset: 4px; }

/* Routes, not an ask. Reuses .contact-list from the contact page. */
.next-steps { padding: 100px 0 120px; background: var(--paper); border-top: 1px solid var(--ink-200); }
.next-steps h2 { max-width: 18ch; }
.next-steps .lede { margin: 20px 0 46px; max-width: 56ch; color: var(--ink-600); font-size: 1.125rem; }

@media (max-width: 640px) {
  .creed > div { grid-template-columns: 1fr; gap: 10px; }
}

/* An anchored scrim, for photographs that are bright exactly where the type
   sits. scrim-deep and scrim-deeper both fade left to right on the assumption
   that the left of the frame is the darker half. A real shopfront breaks that
   assumption: pale pavement runs the full width along the bottom, which is
   where the headline lives, and the graduated scrims measured 2.52:1 against a
   3:1 floor. This one holds a near solid panel over the left third and releases
   it quickly, so the type is safe on any photograph and the right half of the
   picture is left alone. Use it whenever a measurement fails rather than
   hunting for a darker crop. */
.scrim-anchor {
  background:
    linear-gradient(to right,
      rgba(17,17,17,.94) 0%, rgba(17,17,17,.90) 30%,
      rgba(17,17,17,.55) 52%, rgba(17,17,17,.10) 72%, rgba(17,17,17,0) 86%),
    linear-gradient(to top,
      rgba(17,17,17,.72) 0%, rgba(17,17,17,.34) 44%, rgba(17,17,17,0) 82%);
}

/* Plate headlines were inheriting the 940px inner width, so a two line
   headline left a wide empty box running out past the scrim. That is loose
   typography, and it also meant a contrast measurement sampled bare
   photograph to the right of the last word. Hold them to a measure. */
.plate h2 { max-width: 20ch; }

/* The agencies band. Real member photography in the one place it belongs, which
   is a section headed "The agencies that passed". Three frames edge to edge with
   no cards, no borders and no gaps, so it reads as one continuous photograph of
   the network rather than a grid of tiles. The design system bans card grids on
   this page and this is deliberately not one. */
.agency-band {
  display: grid; grid-template-columns: repeat(3, 1fr);
  margin: 40px 0 46px; border-radius: var(--r-md); overflow: hidden;
}
.agency-band img { width: 100%; height: 100%; aspect-ratio: 3 / 2; object-fit: cover; display: block; }
@media (max-width: 720px) {
  /* Two up rather than three, and the third is dropped rather than squeezed to
     a letterbox nobody can read. */
  .agency-band { grid-template-columns: repeat(2, 1fr); }
  .agency-band img:last-child { display: none; }
}

/* ---------------------------------------------------------------
   MEMBERS. The coverage map, and the logo wall.
   --------------------------------------------------------------- */

.coverage { padding: 26px 0 30px; background: var(--paper); }

/* The country is tall and narrow. In a full width frame it fills the height
   and leaves half the width as sea, so the frame stays portrait and the copy
   sits beside it rather than under it. */
.mapshell {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 48px;
  align-items: start;
}
.mapshell .mapview { grid-row: span 4; order: -1; }

.coverage-key { max-width: 52ch; margin-bottom: 4px; }
.coverage-count { font-size: 1.25rem; color: var(--ink-700); margin: 0 0 10px; }
.coverage-count strong { font-stretch: 75%; font-weight: 800; letter-spacing: -.01em; }
.coverage-help { margin: 0; color: var(--ink-500); font-size: 1rem; }

/* The frame. Fixed shape, so the drawing inside it can be moved around without
   the page reflowing every time the reader drags. */
.mapview {
  position: relative;
  /* Matches the viewBox exactly. See inc/coverage.php: a frame that does not
     match its drawing gets letterboxed, and then the marker layer, positioned
     as a percentage of the frame, drifts off the coastline. */
  aspect-ratio: 570 / 760;
  max-height: 84vh;
  overflow: hidden;
  border: 1px solid var(--ink-200);
  border-radius: var(--r-lg);
  background: var(--white);
  container-type: inline-size;
  touch-action: pan-y;
}
.mapview:focus-visible { outline: 3px solid var(--green-800); outline-offset: 3px; }
.mapview.is-live { cursor: grab; }
.mapview.is-dragging { cursor: grabbing; }

/* Two layers over the same coordinate space.
   
   The coastline is an SVG whose zoom is an SVG transform, so it re-renders as
   vectors at every scale. Scaling it with a CSS transform instead rasterises it
   once and stretches the bitmap, which at eight times looked like a smudge.
   
   The markers are HTML, and their layer is only ever TRANSLATED. Their distance
   from the left edge carries the zoom instead, as calc(--x * --k), so nothing
   they contain is ever scaled and no text or dot is resampled. */
.mapsvg {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%; height: 100%;
}
.mapstage {
  position: absolute;
  inset: 0;
  transform: translate(var(--tx), var(--ty));
  transform-origin: 0 0;
}

.land {
  fill: var(--ink-200);
  stroke: var(--ink-300);
  stroke-width: 1;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

/* The Thames. Meaningless at national scale, useful the moment you are in
   London, so it only appears once the reader is close enough for it to help. */
.river {
  fill: none;
  stroke: var(--paper);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.show-codes .river { opacity: 1; }

/* Every marker is a full size overlay, so its percentage position resolves
   against the map rather than against a zero sized dot. */
.pin { position: absolute; inset: 0; pointer-events: none; }

/* Sizes divide by the zoom, so a dot stays a dot and a label stays readable
   however far in the reader has gone. */
.pin-hit {
  position: absolute;
  left: calc(var(--x) * var(--k));
  top: calc(var(--y) * var(--k));
  transform: translate(-50%, -50%);
  width: 26px;
  height: 26px;
  padding: 0; border: 0; background: none;
  border-radius: 50%;
  cursor: pointer;
  pointer-events: auto;
}
.pin-hit::before {
  content: '';
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--green-700);
  box-shadow: 0 0 0 3px rgba(31, 122, 71, .16);
  transition: background var(--dur) var(--ease);
}
.pin-hit:hover::before,
.pin-hit:focus-visible::before {
  background: var(--green-900);
  box-shadow: 0 0 0 6px rgba(31, 122, 71, .26);
}
.pin-hit:focus-visible { outline: 3px solid var(--green-800); outline-offset: 2px; }

/* Two hundred and thirty one codes at national scale is a smudge. They arrive
   when there is room for them, which the script decides on zoom. */
.pin-code {
  position: absolute;
  left: calc(var(--x) * var(--k));
  top: calc(var(--y) * var(--k));
  transform: translate(9px, -1px);
  font-size: 11px;
  font-weight: 700;
  font-stretch: 75%;
  line-height: 1;
  color: var(--green-900);
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.show-codes .pin-code { opacity: 1; }

/* ---- Place names ----
   The map used to hold two shapes, the coastline and the Thames, and no text.
   Finding your own town on that meant recognising its outline. These are the
   towns the network actually works, positioned at the centroid of that town's
   own districts, so the map can never name a place it does not cover.
   Counter scaled like everything else in this layer, so a name stays the size
   of a name however far in the reader has gone. Council Audit critical 3. */
.maptown {
  position: absolute;
  left: calc(var(--x) * var(--k));
  top: calc(var(--y) * var(--k));
  transform: translate(-50%, -22px);
  font-size: 12px;
  font-weight: 700;
  font-stretch: 87%;
  letter-spacing: .01em;
  line-height: 1;
  white-space: nowrap;
  color: var(--ink-700);
  /* Reads over the land fill and over the paper behind it, without a box. */
  paint-order: stroke fill;
  -webkit-text-stroke: 3px var(--paper);
  pointer-events: none;
  opacity: 1;
  transition: opacity var(--dur) var(--ease);
}
/* Tier two is the rest of them, and it waits until there is room. */
.maptown--t2 { opacity: 0; }
.show-towns .maptown--t2 { opacity: 1; }

@media (max-width: 700px) {
  /* Less room, so the second tier stays away and the first sets smaller. */
  .maptown { font-size: 11px; -webkit-text-stroke-width: 2.5px; }
}

/* The panel. Hover, tap and keyboard focus all do the same thing. It is
   counter scaled too, so it is always legible and never covers the country. */
.pin-panel {
  position: absolute;
  left: calc(var(--x) * var(--k));
  top: calc(var(--y) * var(--k));
  z-index: 3;
  display: block;
  width: max-content;
  max-width: 240px;
  padding: 11px 14px;
  font-size: 14px;
  background: var(--ink-900);
  color: var(--white);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-md);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur) var(--ease), visibility var(--dur);
  pointer-events: none;
}
.pin--down .pin-panel { margin-top: 14px; }
.pin--up .pin-panel   { margin-top: -14px; translate: 0 -100%; }
.pin--c .pin-panel { translate: -50% 0; }
.pin--c.pin--up .pin-panel { translate: -50% -100%; }
.pin--r .pin-panel { translate: -100% 0; }
.pin--r.pin--up .pin-panel { translate: -100% -100%; }

.pin-hit:hover ~ .pin-panel,
.pin-hit:focus-visible ~ .pin-panel { opacity: 1; visibility: visible; }
.pin:has(.pin-hit:hover), .pin:has(.pin-hit:focus-visible) { z-index: 20; }
.is-dragging .pin-panel { opacity: 0 !important; visibility: hidden !important; }

.pin-area {
  display: block;
  font-size: .82em;
  font-weight: 800;
  font-stretch: 75%;
  color: var(--green-400);
  margin-bottom: .45em;
}
.pin-area span { font-weight: 600; color: var(--ink-300); }
.pin-member { display: block; line-height: 1.35; }
.pin-member + .pin-member { margin-top: .45em; padding-top: .45em; border-top: 1px solid rgba(255, 255, 255, .16); }
.pin-member strong { display: block; font-weight: 700; }
.pin-office { display: block; font-size: .84em; font-style: italic; color: var(--ink-300); }

/* Controls. Words where a word fits, because an icon alone is a guess. */
.map-controls {
  position: absolute;
  right: 14px; top: 14px;
  z-index: 30;
  display: flex; flex-direction: column; gap: 6px;
  align-items: stretch;
}
.mapbtn {
  min-width: 42px; min-height: 42px;
  display: grid; place-items: center;
  font: inherit; font-size: 1.25rem; font-weight: 700; line-height: 1;
  color: var(--ink-900);
  background: var(--white);
  border: 1px solid var(--ink-200);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
}
.mapbtn--wide {
  font-size: .8125rem; font-weight: 700; font-stretch: 75%;
  padding: 0 12px; min-height: 36px; margin-top: 4px;
}
.mapbtn:hover { background: var(--green-050); border-color: var(--green-200); }
.mapbtn:focus-visible { outline: 3px solid var(--green-800); outline-offset: 2px; }
.mapbtn:disabled { opacity: .4; cursor: default; }
.mapbtn:disabled:hover { background: var(--white); border-color: var(--ink-200); }

/* Only worth saying once the map can actually be dragged. */
.map-hint {
  position: absolute;
  left: 14px; bottom: 12px;
  margin: 0;
  z-index: 30;
  font-size: .8125rem;
  color: var(--ink-500);
  background: rgba(255, 255, 255, .86);
  padding: 4px 9px;
  border-radius: var(--r-pill);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.mapview.is-live .map-hint { opacity: 1; }

/* No script: no controls, no hint, and the map sits at full extent doing the
   one thing it can still do, which is answer on hover. */
.mapview:not(.is-live) .map-controls { display: none; }

.coverage-note {
  margin: 0;
  max-width: 52ch;
  color: var(--ink-500);
  font-size: 1rem;
}

/* The logo wall. It moves, so it stops when you point at it, and it does not
   move at all for anyone who has asked the operating system for stillness. */
.logowall { padding: 84px 0 76px; background: var(--paper); overflow: hidden; }
.logowall h2 { font-size: clamp(1.75rem, 3vw, 2.5rem); }
.logowall-intro { margin: 18px 0 46px; color: var(--ink-600); max-width: 62ch; }

.marquee {
  display: flex;
  width: 100%;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
}
.marquee-track {
  display: flex;
  flex: 0 0 auto;
  margin: 0; padding: 0;
  list-style: none;
  animation: ean-marquee 78s linear infinite;
}
@keyframes ean-marquee { to { transform: translateX(-100%); } }
.marquee:hover .marquee-track,
.marquee:focus-within .marquee-track { animation-play-state: paused; }
/* The explicit control, for everybody hover and focus never reached. */
.marquee--paused .marquee-track { animation-play-state: paused; }
.marquee-controls { display: flex; justify-content: flex-end; margin-bottom: 12px; }
.marquee-pause {
  font: 600 .9375rem/1 var(--font-body); color: var(--ink-700);
  background: none; border: 1px solid var(--ink-200); border-radius: 999px;
  padding: 10px 18px; min-height: 44px; cursor: pointer;
}
.marquee-pause:hover { border-color: var(--green-300); color: var(--green-700); }
.marquee-pause[aria-pressed="true"] { border-color: var(--green-700); color: var(--green-700); }

/* No card, no border, no background. Each logo is a clear PNG sitting on the
   paper, which is what Nick asked for and what a logo wall should look like.
   
   The gap lives on the item rather than on the track, because a track gap is
   not included in the 100% the animation translates by and the loop jumps. */
.chip {
  flex: 0 0 auto;
  width: 224px; height: 112px;
  margin-right: 56px;
  display: grid; place-items: center;
}
.chip img { max-width: 100%; max-height: 100%; width: auto; height: auto; display: block; }

/* Sits in the column beside the map, which is where the question occurs to
   somebody: they have just looked for their town and not found it. */
.nomember { margin-top: 34px; padding-top: 30px; border-top: 1px solid var(--ink-200); }
.nomember h2 { font-size: clamp(1.25rem, 1.8vw, 1.5rem); max-width: 24ch; }
.nomember p { margin: 14px 0 22px; color: var(--ink-600); max-width: 52ch; font-size: 1rem; }

/* Centred on this page only. The homepage version sits left because it follows
   a left aligned narrative down the whole page; here it is the last thing on a
   page whose two columns have just ended, and left aligned it reads as though
   it belongs to a column that is no longer there. */
.book--members { padding: 84px 0 118px; }
.book--members .inner { max-width: 720px; margin-inline: auto; text-align: center; }
/* Wider than the 46ch the left aligned version uses: centred text ragged on
   both edges needs a longer line or every paragraph reads as a diamond. */
.book--members .inner p { max-width: 54ch; margin-left: auto; margin-right: auto; }
.book--members h2 { max-width: 20ch; margin-inline: auto; }
.book--members .actions { justify-content: center; }

.book-terms {
  margin-top: 40px;
  padding-top: 26px;
  border-top: 1px solid rgba(255, 255, 255, .22);
  font-size: .9375rem;
  line-height: 1.6;
  color: rgba(255, 255, 255, .72);
  max-width: 60ch;
}

@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
  .marquee-track--dupe { display: none; }
  .marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .mapstage, .pin-panel, .pin-code, .river, .pin-hit::before { transition: none; }
}

@media (max-width: 900px) {
  .mapshell { grid-template-columns: 1fr; gap: 26px; }
  .mapshell .mapview { order: 0; grid-row: auto; }
  .nomember { margin-top: 8px; }
  .coverage-key { margin-bottom: 0; }
  .mapview { max-height: none; }
}

@media (max-width: 620px) {
  .mapview { aspect-ratio: 3 / 4; border-radius: var(--r-md); }
  .mapbtn { min-width: 44px; min-height: 44px; }
  .chip { width: 176px; height: 88px; margin-right: 34px; }
}

@media print {
  .marquee { display: none; }
  .pin-panel, .map-controls, .map-hint { display: none; }
}

/* ---------------------------------------------------------------
   CONTACT. One form, no address on the page, nothing to harvest.
   --------------------------------------------------------------- */

/* The two enquiries with a better home than the general form, offered before
   it rather than after it. */


/* Six columns rather than two, so name, email and telephone can share a row
   of three and the message and the subject can still run the full width. */
.contact-form { grid-template-columns: repeat(6, 1fr); }
.contact-form .field-wide  { grid-column: span 6; }
.contact-form .field-third { grid-column: span 2; }

@media (max-width: 900px) {
  .contact-form .field-third { grid-column: span 3; }
}
@media (max-width: 620px) {
  .contact-form .field-third { grid-column: span 6; }
}

.office {
  font-style: normal;
  line-height: 1.6;
  color: var(--ink-700);
  margin-bottom: 12px;
}
.rail-note { margin-bottom: 30px; }

@media (max-width: 800px) {
}

/* --------------------------------------------------------------------------
   2026-08-12. Nick's review sweep.
   -------------------------------------------------------------------------- */

/* The "handful of times" statement, split.
   Centred it read as a pull quote with nowhere to go: a very large headline
   with a column of body text hanging off the bottom of it, both centred in a
   full screen. Held apart, the headline is a title and the paragraphs beside
   it are the argument, which is what they are. */
.statement--split { min-height: 0; padding: 130px 34px 140px; }
.statement--split .inner {
  max-width: 1240px;
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
  gap: 48px 88px;
  align-items: start;
}
.statement--split h2 { margin: 0; font-size: clamp(2.25rem, 4.6vw, 4.5rem); max-width: 14ch; }
.statement--split .statement-body p { margin-top: 0; max-width: 52ch; font-size: 1.1875rem; }
.statement--split .statement-body p + p { margin-top: 24px; color: var(--ink-700); }

@media (max-width: 900px) {
  .statement--split { padding: 96px 34px 100px; }
  .statement--split .inner { grid-template-columns: 1fr; gap: 32px; }
  .statement--split h2 { max-width: 18ch; }
}

/* The agencies section on the homepage now carries the scrolling logo wall
   instead of forty typeset names. The marquee is full bleed, so the section
   clips rather than the page, and the heading and the footnote keep their
   .wrap either side of it. */
.agencies--wall { overflow: hidden; padding-bottom: 104px; }
.agencies--wall .marquee { margin: 56px 0 50px; }
.agencies--wall .after { margin-top: 0; }

/* Members page. Nick: "there needs to be a bit more of a gap because that
   feels a bit too compressed." The intro sat 46px above a 112px tall row of
   logos, which reads as one block rather than a heading and then a wall. */
.logowall-intro { margin-bottom: 68px; }

/* A promise block that leads with a lede paragraph rather than going straight
   from the heading into the list. Used on /approved-agents/. */
.promise-block .lede + .promises { margin-top: 52px; }

/* The FAQ page. Wider and single column: these answers are three and four
   sentences long, and the homepage's two column treatment was built for the
   short ones that used to run there. */

/* A closing note that is the only thing in its section, rather than a footnote
   under a checklist. It brings its own top rule normally; here the section
   edge already provides one. */
.checklist-page > .wrap > .checklist-after:first-child {
  margin-top: 0; padding-top: 0; border-top: 0;
}

/* ---------------------------------------------------------------
   THE ADVICE SECTION, 2026-08-12. Cards, and an audience filter.
   The front door bans card grids; this is not the front door. It is an index
   of 190-odd articles, which is exactly what a card grid is for.
   --------------------------------------------------------------- */
.cards-section { padding: 10px 0 110px; background: var(--paper); }

.filter { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 48px; }
.filter-tab {
  display: inline-flex; align-items: center;
  padding: 10px 20px; border-radius: var(--r-pill);
  border: 1px solid var(--ink-200); background: var(--white);
  color: var(--ink-700); text-decoration: none;
  font-size: .9375rem; font-weight: 700;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.filter-tab:hover { border-color: var(--green-200); background: var(--green-050); color: var(--green-800); }
.filter-tab.is-on { background: var(--green-700); border-color: var(--green-700); color: var(--white); }

.cards {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 44px 34px;
}
.card a {
  display: flex; flex-direction: column; height: 100%;
  text-decoration: none; color: inherit;
}
.card-shot {
  display: block; position: relative; overflow: hidden;
  border-radius: var(--r-md); background: var(--green-900);
  aspect-ratio: 8 / 5;
}
.card-shot img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 520ms var(--ease);
}
.card a:hover .card-shot img { transform: scale(1.03); }

/* A card with no picture. Two thirds of the migrated archive has no featured
   image, and a grid of grey placeholder boxes reads as a broken page. The
   title set large on the brand green is the picture instead. */
.card--plain .card-shot { display: grid; align-items: end; padding: 22px; }
.card-mark {
  font-stretch: 75%; font-weight: 800; letter-spacing: -.02em;
  font-size: 1.375rem; line-height: 1.12; color: rgba(255,255,255,.30);
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}

.card-body { display: block; padding-top: 16px; }
.card-meta { display: block; color: var(--ink-500); font-size: .8125rem; font-weight: 700; letter-spacing: .02em; text-transform: uppercase; }
.card-title {
  display: block; margin-top: 8px;
  font-stretch: 75%; font-weight: 800; letter-spacing: -.01em;
  font-size: 1.1875rem; line-height: 1.24; color: var(--ink-900);
}
.card a:hover .card-title { color: var(--green-800); }
.card-note { display: block; margin-top: 9px; color: var(--ink-600); font-size: .9375rem; line-height: 1.55; }

.crumb { margin: 0 0 34px; }
.crumb a { color: var(--green-800); font-weight: 600; text-decoration: none; border-bottom: 1px solid var(--green-200); }
.crumb a:hover { border-bottom-color: var(--green-700); }

@media (max-width: 1000px) { .cards { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px)  { .cards { grid-template-columns: 1fr; gap: 34px; } }
}

/* ---------------------------------------------------------------
   FOR AGENTS. What lands each month.
   --------------------------------------------------------------- */

/* Full bleed graphics with their words underneath. The supplied artwork is
   1900x800 with its own generous paper margins and its own left hand type, so
   it wants the whole width and nothing boxed around it. */
.lands { padding: 10px 0 40px; background: var(--paper); }
.lands > .wrap > h2 { max-width: 20ch; }
/* One line, per Nick. "What lands every month." is 23 characters and was
   breaking after the second word at the old measure. */
.lands-h { max-width: none !important; }
.lands .lede { max-width: 54ch; color: var(--ink-600); margin: 18px 0 0; font-size: 1.125rem; }

.land { margin-top: 72px; }
/* The artwork carries its own generous paper margins, so it sits inside the
   page gutter rather than bleeding. That also lines its own left hand type up
   with the words underneath it. */
.land img { display: block; width: 100%; height: auto; }
/* The words fill the same width the artwork does.
   Nick, 2026-08-12: "the bit of text underneath is not full width, but the
   image below it is." A 60ch paragraph under a full width graphic reads as a
   caption that did not stretch, rather than as a deliberate measure. Two
   columns fills the width without setting a 110 character line. */
.land-words {
  margin-top: 24px;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: 10px 62px;
  align-items: start;
}
.land-words h3 { font-size: clamp(1.375rem, 2.2vw, 1.875rem); max-width: 20ch; margin: 0; }
.land-words p { margin: 0; color: var(--ink-600); line-height: 1.65; font-size: 1.0625rem; }

@media (max-width: 820px) {
  .land-words { grid-template-columns: 1fr; gap: 12px; }
}

/* A row with no artwork. It carries a rule and more air so it reads as one of
   the set rather than as something that failed to load. */
.land--type { margin-top: 84px; padding-top: 60px; border-top: 1px solid var(--ink-200); }
.land--type .land-words { margin-top: 0; }

/* The whole team section. Two columns of short blocks. */
.whole-team { padding: 96px 0 100px; background: var(--paper); border-top: 1px solid var(--ink-200); }
.whole-team h2 { max-width: 24ch; }
.whole-team .lede { max-width: 54ch; color: var(--ink-600); margin: 20px 0 0; font-size: 1.125rem; }
.team-points {
  list-style: none; margin: 54px 0 0; padding: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 0 62px;
}
.team-points li { padding: 28px 0; border-top: 1px solid var(--ink-200); }
.team-points h3 { font-size: clamp(1.125rem, 1.9vw, 1.4375rem); max-width: 28ch; }
.team-points p { margin-top: 10px; color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6; max-width: 48ch; }

@media (max-width: 820px) {
  .team-points { grid-template-columns: 1fr; }
  .land { margin-top: 54px; }
}

/* ---------------------------------------------------------------
   ABOUT US, 2026-08-12 rebuild.
   --------------------------------------------------------------- */

/* Who runs it. The existing .people list was two names and a role each; these
   carry a paragraph, so the columns become a grid and the role gets a rule
   under it. */
.people--bios { columns: auto; display: grid; grid-template-columns: 1fr 1fr; gap: 0 62px; }
.people--bios li { padding: 26px 0 30px; }
.people--bios .person-role { color: var(--green-800); font-weight: 600; }
.person-body { margin-top: 14px; color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6; max-width: 46ch; }
.person-photo {
  display: block; width: 100%; height: auto; aspect-ratio: 1 / 1;
  object-fit: cover; border-radius: var(--r-md); margin-bottom: 20px;
}

/* Two frames of the same person, crossfaded on hover. Enhancement only:
   touch and keyboard readers get the first frame and lose nothing. */
.person-photo--swap { position: relative; overflow: hidden; }
.person-photo--swap img {
  display: block; width: 100%; height: 100%; aspect-ratio: 1 / 1;
  object-fit: cover; border-radius: var(--r-md);
}
.person-photo--swap .swap-hover {
  position: absolute; inset: 0; opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.person-photo--swap:hover .swap-hover { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .person-photo--swap .swap-hover { transition: none; }
}
.team-note {
  margin-top: 44px; padding-top: 34px; border-top: 1px solid var(--ink-200);
  max-width: 62ch; color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6;
}

/* Quotes. Renders only when there is something real to quote. */
.quotes { padding: 20px 0 96px; background: var(--paper); }
.pull { position: relative; margin: 0 0 48px; padding: 0 0 0 42px; max-width: 60ch; }
/* The colour lives in a drawn quotation mark rather than a coloured stripe down
   the side. A pull quote reads as a quote from its size and its attribution. */
.pull::before {
  content: "\201C";
  position: absolute;
  left: 0; top: -.06em;
  font-size: 3.25rem;
  line-height: 1;
  font-weight: 800;
  color: var(--green-500);
}
.pull p { font-size: clamp(1.25rem, 2.4vw, 1.75rem); line-height: 1.42; color: var(--ink-900); }
.pull cite { display: block; margin-top: 18px; font-style: normal; }
.pull-name { display: block; font-weight: 800; font-stretch: 75%; letter-spacing: -.01em; }
.pull-role { display: block; margin-top: 2px; color: var(--ink-500); font-size: .9375rem; }

/* Three captioned photographs. Captions because an uncaptioned photograph on a
   page about transparency is decoration. */
.band { padding: 10px 0 100px; background: var(--paper); }
.band-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px; }
.band-list li { display: flex; flex-direction: column; }
.band-list img { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; display: block; border-radius: var(--r-md); }
.band-cap { display: block; margin-top: 14px; color: var(--ink-600); font-size: .9375rem; line-height: 1.5; }

.standard-foot {
  margin-top: 56px; padding-top: 34px; border-top: 1px solid var(--ink-200);
  max-width: 66ch; color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6;
}

@media (max-width: 900px) {
  .people--bios { grid-template-columns: 1fr; }
  .band-list { grid-template-columns: 1fr; gap: 34px; }
}

/* ---------------------------------------------------------------
   THE KARMA CLUB.
   --------------------------------------------------------------- */

/* The figure. Green field, one number, said once. Reuses the proof sequence's
   voice without its scroll machinery, which belongs to the homepage. */

/* The causes. Renders only when there are causes to name. */
.causes { padding: 96px 0 100px; background: var(--paper); }
.causes h2 { max-width: 22ch; }
.causes .lede { max-width: 56ch; color: var(--ink-600); margin: 20px 0 0; font-size: 1.125rem; }
.cause-list {
  list-style: none; margin: 54px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px 44px;
}
.cause-list li { padding-top: 24px; border-top: 1px solid var(--ink-200); }
.cause-logo { display: grid; place-items: start; height: 72px; margin-bottom: 16px; }
.cause-logo img { max-width: 180px; max-height: 72px; width: auto; height: auto; display: block; }
.cause-name { display: block; font-weight: 800; font-stretch: 75%; letter-spacing: -.01em; font-size: 1.125rem; }
.cause-name a { color: var(--green-800); text-decoration: none; border-bottom: 1px solid var(--green-200); }
.cause-name a:hover { border-bottom-color: var(--green-700); }
.cause-where { display: block; margin-top: 3px; color: var(--ink-500); font-size: .9375rem; }
.cause-note { display: block; margin-top: 10px; color: var(--ink-600); font-size: 1rem; line-height: 1.55; }

/* Two photographs rather than three. */
.band-list--pair { grid-template-columns: 1fr 1fr; gap: 34px; }
.band-list--pair img { aspect-ratio: 3 / 2; }

@media (max-width: 900px) {
  .cause-list { grid-template-columns: 1fr 1fr; }
  .band-list--pair { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  .cause-list { grid-template-columns: 1fr; }
}

/* 2026-08-12. Nick asked for more air between the plate that says membership
   is not guaranteed and the section that says who runs it. They were 10px
   apart, so the photograph read as though it belonged to the team section. */
.plate + .team { padding-top: 96px; }

/* A pull quote inside an article body. .entry blockquote styles it as a
   generic editor blockquote, which fights the .pull treatment; .pull wins and
   keeps its own margins in prose. */
.entry .pull { margin: 40px 0 44px; padding: 0 0 0 42px; background: none; font-style: normal; }
.entry .pull p { font-size: clamp(1.25rem, 2.2vw, 1.625rem); line-height: 1.35; color: var(--ink-900); margin: 0; }

/* ---------------------------------------------------------------
   THE KARMA CLUB, 2026-08-12 rebuild.
   --------------------------------------------------------------- */

/* The Club has its own logo and its own strapline. It sits above the H1
   because this is the one page on the site that is not speaking as the
   network. */
.page-head--karma { padding-top: 170px; }
.karma-logo { display: block; width: 260px; height: auto; margin-bottom: 34px; }

/* What the money paid for. The amount is the largest thing in the row,
   because the smallness of the amounts is the entire argument. */
.gave-section { padding: 96px 0 40px; background: var(--paper); }
.gave-section h2 { max-width: 18ch; }
.gave-section .lede { max-width: 62ch; color: var(--ink-600); margin: 20px 0 0; font-size: 1.125rem; line-height: 1.6; }

.gave { list-style: none; margin: 54px 0 0; padding: 0; max-width: 1000px; }
.gave li {
  display: grid; grid-template-columns: 132px minmax(0, 1fr);
  gap: 4px 28px;
  padding: 30px 0; border-top: 1px solid var(--ink-200);
}
.gave li:last-child { border-bottom: 1px solid var(--ink-200); }
.gave-sum {
  grid-row: span 2;
  font-stretch: 75%; font-weight: 800; letter-spacing: -.02em;
  font-size: clamp(1.5rem, 3vw, 2.25rem); line-height: 1.05;
  color: var(--green-700);
}
.gave-what {
  font-stretch: 75%; font-weight: 800; letter-spacing: -.01em;
  font-size: clamp(1.125rem, 2vw, 1.4375rem); line-height: 1.22;
  color: var(--ink-900); max-width: 34ch;
}
.gave-note { color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6; max-width: 62ch; }
.gave-after {
  margin-top: 40px; padding-top: 30px; border-top: 1px solid var(--ink-200);
  max-width: 62ch; color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6;
}

/* Four illustrative photographs, two up. */
.band--places { padding-top: 60px; }
.band--places .band-list { grid-template-columns: repeat(3, 1fr); gap: 34px; }
.band--places .band-list img { aspect-ratio: 3 / 2; }

/* ⚠️ The disclaimer under them. Quiet, but it must stay visible. */
.band-note {
  margin: 40px 0 0; padding-top: 26px; border-top: 1px solid var(--ink-200);
  max-width: 68ch; color: var(--ink-500); font-size: .9375rem; line-height: 1.6;
}

.article--tail { padding-top: 90px; }

@media (max-width: 820px) {
  .gave li { grid-template-columns: 1fr; gap: 6px; padding: 24px 0; }
  .gave-sum { grid-row: auto; }
  .band--places .band-list { grid-template-columns: 1fr; }
  .karma-logo { width: 210px; }
}

/* ---------------------------------------------------------------------------
   THE KARMA CLUB PAGE, rebuilt 2026-08-13.

   Nick: "the images are all bunched together, look too generic ... and work on
   the general layout of the page which is currently not great."

   The layout fault was that every section was the same 680px column pinned to
   the left of a 1200px wrap, nine times down the page, so half the desktop was
   permanently empty and nothing ever changed shape. These rules give the page
   a rhythm: full bleed photograph, split, narrow, full width quote, three
   across, wide list, three across, split. Reading measure is unchanged where
   it matters, which is the prose.
   --------------------------------------------------------------------------- */

/* Defined here because this is a hand coded theme and nothing else supplies
   it. Used where a cell is deliberately empty and a sighted reader sees a
   rule; a screen reader needs the reason, not silence. */
.screen-reader-text {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* The one full bleed image on the page, straight under the headline. */
.karma-hero { background: var(--paper); }
.karma-hero img {
  display: block;
  width: 100%;
  height: clamp(280px, 42vw, 620px);
  object-fit: cover;
}

/* Text one side, photograph the other. .karma-split puts the words first,
   .karma-proud puts the photograph first, so the two do not read as the same
   section twice. */
.karma-split, .karma-proud { padding: 96px 0; background: var(--paper); }
.karma-split .inner, .karma-proud .inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 64px;
  align-items: center;
}
.karma-words h2 { margin-top: 0; }
.karma-words p { max-width: 52ch; }
.karma-fig { margin: 0; }
.karma-fig img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--r-md);
}

/* The page's green anchor. This band used to carry the total raised, which is
   a number the network can be held to and which three of its own sites already
   disagree about. A quote does the same work visually and promises nothing. */
.karma-quote { padding: 96px 0 100px; background: var(--green-800); color: var(--white); }
/* Explicit px, not ch. A ch measure on this element resolves against the
   blockquote's own 1rem font rather than the 3.25rem paragraph inside it,
   which set the quote one word per line. */
.karma-quote blockquote { margin: 0; max-width: 940px; }
.karma-quote p {
  margin: 0;
  font-size: clamp(1.75rem, 4vw, 3.25rem);
  line-height: 1.18;
  font-weight: 800;
  font-stretch: 75%;
  letter-spacing: -.02em;
}
.karma-quote cite { display: block; margin-top: 34px; font-style: normal; }
.karma-quote .pull-name { color: var(--white); }
.karma-quote .pull-role { color: rgba(255,255,255,.72); }

/* How it works, as three steps across the full width rather than three more
   paragraphs in the same left hand column. */
.karma-how { padding: 96px 0 40px; background: var(--paper); }
.karma-how > .wrap > h2 { max-width: 20ch; }
.how-list {
  list-style: none;
  margin: 54px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 44px;
}
.how-list li { border-top: 2px solid var(--green-600); padding-top: 22px; }
.how-num {
  display: block;
  font-size: 1rem;
  font-weight: 800;
  font-stretch: 75%;
  color: var(--green-700);
  margin-bottom: 12px;
}
.how-list h3 { margin: 0 0 12px; font-size: 1.3125rem; }
.how-list p { margin: 0; color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6; }

/* Where a gift has no published amount the cell carries a drawn rule. A typed
   dash would be an em dash, which is banned in everything written for Nick. */
.gave-sum--none::before {
  content: "";
  display: block;
  width: 26px;
  height: 3px;
  margin-top: .55em;
  background: var(--green-600);
  border-radius: 2px;
}

.karma-tail { border-top: 1px solid var(--ink-200); }

@media (max-width: 900px) {
  .karma-split, .karma-proud { padding: 64px 0; }
  .karma-split .inner, .karma-proud .inner { grid-template-columns: 1fr; gap: 36px; }
  /* On one column the photograph belongs under the words it illustrates, in
     both sections, rather than above them in one and below in the other. */
  .karma-proud .karma-fig { order: 2; }
  .karma-quote { padding: 72px 0 76px; }
  .karma-quote blockquote { max-width: none; }
  .how-list { grid-template-columns: 1fr; gap: 34px; }
  .karma-hero img { height: clamp(220px, 56vw, 340px); }
}

/* ---------------------------------------------------------------------------
   THE PROMISE PAGE, photographs added 2026-08-13.
   Nick: "the main promises are there, but there is no images which makes the
   page boring." Eight long sentences in one run needed breaking, not
   decorating, so the pictures carry the joins between blocks of four.

   ⚠️ Every photograph on this page is of one real, named member agency, so
   every one carries a visible credit. .shot-credit is that credit and it is not
   decoration: it is the condition on which the photographs are used.
   --------------------------------------------------------------------------- */

.promise-shot { background: var(--paper); padding: 0 0 20px; }
.promise-shot figure { margin: 0; }
.promise-shot img {
  display: block;
  width: 100%;
  height: clamp(280px, 44vw, 620px);
  object-fit: cover;
  /* Bias the crop upward. A centred crop on the team photograph took the top
     off the heads at the back of the group, which is the one thing a group
     photograph must not do. */
  object-position: center 38%;
}
.promise-shot figcaption {
  max-width: var(--max);
  margin: 16px auto 0;
  padding: 0 32px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  align-items: baseline;
}
.shot-cap { color: var(--ink-600); font-size: 1.0625rem; line-height: 1.55; max-width: 62ch; }
/* Small, quiet, and always present. A credit that is easy to miss is still a
   credit; a credit that is absent is a photograph taken without saying whose
   it is. */
.shot-credit {
  color: var(--ink-500);
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: .02em;
  white-space: nowrap;
}

.promise-page--second { padding-top: 0; }

/* The break between the two blocks of four. */
.promise-aside { background: var(--paper); padding: 76px 0 84px; }
.promise-aside .inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 56px;
  align-items: center;
}
.promise-aside-fig { margin: 0; }
.promise-aside-fig img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 3 / 2; object-fit: cover;
  border-radius: var(--r-md);
}
.promise-aside-fig figcaption { margin-top: 12px; }
.promise-aside-words h2 { margin: 0 0 18px; font-size: clamp(1.75rem, 3vw, 2.5rem); max-width: 18ch; }
.promise-aside-words p { margin: 0; color: var(--ink-700); font-size: 1.1875rem; line-height: 1.62; max-width: 48ch; }

@media (max-width: 900px) {
  .promise-aside { padding: 56px 0 60px; }
  .promise-aside .inner { grid-template-columns: 1fr; gap: 30px; }
  .promise-shot img { height: clamp(220px, 52vw, 340px); }
  .promise-shot figcaption { padding: 0 16px; }
}

/* ---------------------------------------------------------------------------
   THE STEP BY STEP FUNNEL, 2026-08-13.

   One question at a time, for the valuation booking and the agency
   application. Built big and calm on purpose: all three users of the sister
   product have ADHD and one is severely dyslexic, so the type is large, the
   density is low, nothing moves on its own and nothing advances by itself.

   ⚠️ Every step is visible and the plain submit is shown UNTIL the script says
   otherwise. Without JavaScript this is one long working form, which is the
   only reason it is safe to put every lead on the site through it.
   --------------------------------------------------------------------------- */

.funnel-section { padding: 10px 0 90px; background: var(--paper); }
.funnel { max-width: 720px; }

/* Where you are. Words, not a row of dots: "Step 2 of 6" and the name of the
   screen, because a dot tells a reader nothing about how much is left. */
.funnel-progress { margin-bottom: 38px; }
.funnel-count {
  margin: 0; font-size: .9375rem; font-weight: 700;
  letter-spacing: .02em; color: var(--green-700);
}
.funnel-where { margin: 4px 0 14px; font-size: 1.0625rem; color: var(--ink-600); }
.funnel-bar { height: 6px; background: var(--ink-200); border-radius: 999px; overflow: hidden; }
/* scaleX, not width. Animating width forces a layout on every frame of the
   transition; a transform is composited and never touches layout. */
.funnel-bar span {
  display: block; height: 100%; width: 100%;
  transform: scaleX(0); transform-origin: left center;
  background: var(--green-600); border-radius: 999px;
  transition: transform var(--dur) var(--ease);
}

.funnel-step { border: 0; margin: 0; padding: 0; }
.funnel-step + .funnel-step { margin-top: 54px; }
.funnel-step legend {
  padding: 0; margin: 0 0 10px;
  font-size: clamp(1.5rem, 3vw, 2.125rem);
  font-weight: 800; font-stretch: 75%; letter-spacing: -.02em;
  color: var(--ink-900);
}
.funnel-step legend:focus-visible { outline: 2px solid var(--green-600); outline-offset: 4px; }
.funnel-intro { margin: 0 0 26px; color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6; max-width: 56ch; }

.funnel-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.funnel-fields .field-wide { grid-column: 1 / -1; }
.funnel label { display: block; font-weight: 700; font-size: 1.0625rem; color: var(--ink-900); margin-bottom: 8px; }
.funnel .optional { font-weight: 400; color: var(--ink-500); margin-left: 6px; }
.funnel .hint { margin: -2px 0 10px; font-size: .9375rem; line-height: 1.45; color: var(--ink-500); }

.funnel input[type="text"],
.funnel input[type="email"],
.funnel input[type="tel"],
.funnel input[type="url"],
.funnel select,
.funnel textarea {
  width: 100%; font: inherit; font-size: 1.125rem;
  padding: 15px 16px; color: var(--ink-900); background: var(--white);
  border: 1px solid var(--ink-200); border-radius: var(--r-md);
  transition: border-color var(--dur) var(--ease);
}
.funnel textarea { resize: vertical; min-height: 130px; line-height: 1.55; }
.funnel select { appearance: none; padding-right: 42px; }
.funnel input:focus-visible,
.funnel select:focus-visible,
.funnel textarea:focus-visible { border-color: var(--green-500); outline: 2px solid var(--green-500); outline-offset: 1px; }

/* Consent. Big target, label beside the box, whole line clickable. */
.field-check label {
  display: grid; grid-template-columns: 26px minmax(0, 1fr);
  gap: 14px; align-items: start;
  font-weight: 400; font-size: 1.0625rem; line-height: 1.55;
  color: var(--ink-800); cursor: pointer;
  padding: 16px 18px; border: 1px solid var(--ink-200);
  border-radius: var(--r-md); background: var(--white);
}
.field-check label:hover { border-color: var(--green-300); }
.field-check input { width: 26px; height: 26px; margin: 0; accent-color: var(--green-700); }

.field-error { margin: 8px 0 0; color: #a4231f; font-size: .9375rem; font-weight: 600; }
.field--bad input, .field--bad select, .field--bad textarea { border-color: #a4231f; }
.field--bad .field-check label { border-color: #a4231f; }

.funnel-nav { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 40px; align-items: center; }
/* Words, never an icon on its own. A bare chevron is a guess, not a control. */
.funnel-nav .btn { min-width: 128px; justify-content: center; }
.funnel-plain { margin-top: 40px; }

.funnel-note {
  margin-top: 26px; max-width: 56ch;
  font-size: .9375rem; line-height: 1.5; color: var(--ink-500);
}
.funnel-note a { color: var(--green-800); text-decoration: underline; text-underline-offset: 3px; }

/* What used to be a rail beside the form, now read once underneath it. */

.page-head--tight { padding-bottom: 40px; }

@media (max-width: 700px) {
  .funnel-fields { grid-template-columns: 1fr; gap: 20px; }
  .funnel-nav .btn { flex: 1 1 auto; }
}

@media (prefers-reduced-motion: reduce) {
  .funnel-bar span { transition: none; }
}

/* The standard page reuses the Karma Club's three-across step list for four
   items, and adds a quieter second paragraph under each. */
.how-list--four { grid-template-columns: repeat(4, 1fr); gap: 34px; }
/* An optional link under one of the four. Added 2026-09-03 so The standard can
   point at the eight promises rather than reprint them. */
.how-list .how-link { margin: 14px 0 0; font-size: 1rem; }
.how-note { margin-top: 12px !important; font-size: .9375rem !important; color: var(--ink-500) !important; }

@media (max-width: 1100px) {
  .how-list--four { grid-template-columns: repeat(2, 1fr); gap: 40px 34px; }
}
@media (max-width: 700px) {
  .how-list--four { grid-template-columns: 1fr; }
}

/* The Problem / Risk / Solution / Benefit beat labels on the approved agent
   page. Small, green, and above the heading, so the reader can feel the shape
   of the argument without it being spelled out in prose. */
.beat {
  margin: 0 0 10px;
  font-size: .875rem;
  font-weight: 800;
  font-stretch: 75%;
  letter-spacing: .04em;
  /* Sentence case, not caps. The design system says sentence case and the
     people this site is built for read caps slower, not faster. */
  color: var(--green-700);
}
.article--risk { padding-top: 0; }

/* The chronology on About us. Same three column shape as the Karma Club's list
   of gifts, because it is the same job: a date, a headline, and the detail. */
.story-section { padding: 90px 0 40px; background: var(--paper); }
.story-section > .wrap > h2 { max-width: 18ch; }
.story-section .lede { max-width: 56ch; color: var(--ink-600); margin: 18px 0 0; font-size: 1.125rem; line-height: 1.6; }
.story { list-style: none; margin: 50px 0 0; padding: 0; }
.story li {
  display: grid;
  grid-template-columns: 190px minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 0 40px;
  padding: 30px 0;
  border-top: 1px solid var(--ink-200);
}
.story li:last-child { border-bottom: 1px solid var(--ink-200); }
.story-when { font-weight: 800; font-stretch: 75%; letter-spacing: -.01em; color: var(--green-700); font-size: 1.0625rem; padding-top: .1em; }
.story-what { font-weight: 800; font-stretch: 75%; letter-spacing: -.015em; font-size: 1.25rem; line-height: 1.3; color: var(--ink-900); }
.story-body { color: var(--ink-600); font-size: 1.0625rem; line-height: 1.6; }

@media (max-width: 900px) {
  .story li { grid-template-columns: 1fr; gap: 8px; padding: 24px 0; }
}

/* The FAQ is now three runs with a photograph between them rather than sixteen
   questions in one unbroken column. */
.faq-run {
  margin: 0 0 34px;
  font-size: clamp(1.375rem, 2.4vw, 1.875rem);
  max-width: 24ch;
}

/* ---------------------------------------------------------------------------
   THE FAQ, rebuilt as native disclosure 2026-08-13.

   Nick: "its really text heavy, it should be more of a FAQ so prehaps having
   callapsable questions." Sixteen open answers is an essay with headings; a
   reader looking for one answer walks past fifteen they did not ask.

   ⚠️ <details> and <summary>, no JavaScript. Keyboard accessible, announced
   correctly, and it still works if a script fails. Do not replace it with a
   hand rolled accordion.
   --------------------------------------------------------------------------- */

.faq-page { padding: 20px 0 110px; background: var(--paper); }
.faq-run {
  margin: 64px 0 8px;
  font-size: clamp(1.25rem, 2.2vw, 1.5rem);
  color: var(--ink-500);
  font-weight: 700;
  max-width: 30ch;
}
.faq-run:first-child { margin-top: 54px; }
.faq-list { max-width: 820px; }

.faq-item { border-bottom: 1px solid var(--ink-200); }
.faq-item:first-of-type { border-top: 1px solid var(--ink-200); }

.faq-item summary {
  /* Strip the default triangle in every engine, then draw our own. */
  list-style: none;
  cursor: pointer;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 28px;
  gap: 20px;
  align-items: start;
  padding: 26px 2px;
  font-size: clamp(1.0625rem, 1.7vw, 1.25rem);
  font-weight: 700;
  line-height: 1.4;
  color: var(--ink-900);
  transition: color var(--dur) var(--ease);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--green-800); }
.faq-item summary:focus-visible {
  outline: 2px solid var(--green-600);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

/* Drawn from borders, in the same weight as the navigation caret, rather than
   a unicode arrow standing in for an icon. */
.faq-item summary::after {
  content: "";
  justify-self: end;
  width: 10px; height: 10px;
  margin-top: .45em;
  border-right: 2px solid var(--green-700);
  border-bottom: 2px solid var(--green-700);
  transform: rotate(45deg);
  transition: transform var(--dur) var(--ease);
}
.faq-item[open] summary::after { transform: rotate(-135deg); }
.faq-item[open] summary { color: var(--green-800); }

.faq-answer { padding: 0 60px 30px 2px; }
.faq-answer p {
  margin: 0;
  color: var(--ink-700);
  font-size: 1.0625rem;
  line-height: 1.65;
  max-width: 68ch;
}

@media (prefers-reduced-motion: reduce) {
  .faq-item summary, .faq-item summary::after { transition: none; }
}

/* ---------------------------------------------------------------------------
   CONTACT, distilled 2026-08-13. One form, one heading, one column.
   --------------------------------------------------------------------------- */

.contact-page { padding: 10px 0 110px; background: var(--paper); }
.contact-page .booking { max-width: 720px; }

/* A quiet line, not two cards with two buttons competing with the real form. */
.contact-elsewhere {
  margin: 0 0 44px;
  color: var(--ink-500);
  font-size: 1.0625rem;
  line-height: 1.6;
}
.contact-elsewhere a {
  color: var(--green-800);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.contact-address {
  margin: 56px 0 0;
  padding-top: 26px;
  border-top: 1px solid var(--ink-200);
  max-width: 720px;
  font-style: normal;
  color: var(--ink-500);
  font-size: .9375rem;
  line-height: 1.6;
}
.contact-address-label { font-weight: 700; color: var(--ink-700); }

/* THE MEMBER BADGE, and why there is almost nothing here.
   Nick's brief on 2026-09-03 was to build familiarity with the roundel members
   display. The first attempt pasted the vector above the heading on six pages
   and he rejected it as sloppy and cheap, correctly: one identical device six
   times, the mark never part of anything, hovering over headlines like a
   bolted-on widget.
   ⚠️ THE RULE THAT CAME OUT OF IT: this badge is shown as a REAL OBJECT IN A
   PHOTOGRAPH, never as artwork floating on a page. The site already did this
   well and nobody had noticed: stickers on a door on Why use an approved agent,
   a member holding the printed brochure on The eight promises, directors with
   their plaque on Why join. The homepage now has the same, on its own plate,
   directly under the section that names the badge.
   `ean_member_badge()` in functions.php still exists and is currently used
   nowhere. Read its docblock before reaching for it. */

}
