/* ==========================================================================
   Cambourne Financial Planning — brand tokens
   Palette A, confirmed by Simon 2026-08-21: the live site's own values, taken
   from cambournefp.co.uk rather than the static prototype (whose palette was
   an unsigned-off approximation).

   This file is the ONLY per-client file. Everything else in the theme is the
   shared Baseplate engine — do not edit theme files to rebrand.

   Deploy to: wp-content/themes/Baseplate/public/baseplate-brand.css
   ========================================================================== */

/* Fonts are imported here rather than via setup.php's google-fonts function, so
   that all client branding lives in this one file.
   ⚠️ CHANGED 2026-08-22: Simon adopted the design preview wholesale, so the type
   is now Source Serif 4 + Inter, not Georgia + Open Sans. See the ledger §2. */
@import url('https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,opsz,wght@0,8..60,300..700;1,8..60,300..700&family=Inter:wght@300;400;500;600;700&display=swap');

:root{
  /* --- Ink ------------------------------------------------------------- */
  /* #0c2340, not the preview's #15294a. Settled 2026-08-23 (Simon: "do what is
     best and run with it"): the Hero panels already used live's #0c2340, so the
     two were inconsistent, and on the #6393cd next-service band the More Info
     link was 4.48:1 at #15294a -- under WCAG AA. At #0c2340 it is 4.95:1 and
     passes, which matters for a regulated firm. This closes decision 2 in
     ledger section 9. */
  --ink:#0c2340;                    /* navy — headings */
  --grey:#5b6470;                   /* body copy (preview) */
  --mid:#2d323b;
  --dim:#a8aeb6;
  --dark:#1d3556;                   /* navy-soft (preview) */

  /* --- Accent ---------------------------------------------------------- */
  /* The base names this token --yellow. It is the accent slot, whatever the
     colour. For Cambourne it is the mid blue used across the live site. */
  --yellow:#2f6fb0;
  /* CORRECTED 2026-08-23. This had drifted to #2f6fb0 while the pattern
     library, the Hero block's panel colour, the five value icons and the live
     site all use #6393cd. The result was two different blues on one page: a
     #6393cd hero directly above a #2f6fb0 next-service band. Measured, not
     chosen. Everything keyed to --accent now matches the hero. */
  --accent:#6393cd;
  --accent-deep:#1f4d7a;

  /* --- Surfaces -------------------------------------------------------- */
  --paper:#ffffff;
  --mist:#f4f5f7;                   /* alternating section background (preview) */
  --border:#e4e7ec;
  --color-shade-1000:#15294a;
  --color-shade-300:#e4e7ec;

  /* --- Type ------------------------------------------------------------ */
  /* The base names the headline token --poppins. It is the headline slot. */
  --poppins:"Source Serif 4",Georgia,"Times New Roman",serif;
  --serif:"Source Serif 4",Georgia,"Times New Roman",serif;
  --sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --font-family-sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;

  /* --- Measure --------------------------------------------------------- */
  --wrap:1180px;                    /* wide sections (preview) */
  --measure:928px;                  /* reading sections */

  /* --- Misc ------------------------------------------------------------ */
  --gap:10px;
  --radius:4px;                     /* the live site is squarer than the base */
  --plyr-color-main:#2f6fb0;
}

/* --------------------------------------------------------------------------
   Baseline treatment
   The engine's compiled CSS reads the tokens above. These few rules set what
   the tokens alone do not: body type, heading family, and the accent on the
   kit blocks that ship with a hard-coded placeholder.
   -------------------------------------------------------------------------- */

body{
  font-family:var(--sans);
  color:var(--grey);
}

h1,h2,h3,h4,h5,h6,
.baseplate-tabs-nav,
.wp-block-kadence-advancedheading{
  font-family:var(--poppins);
  color:var(--ink);
  font-weight:400;
}

a{ color:var(--accent); }
a:hover{ color:var(--accent-deep); }

/* The Testimonial block writes its background as an INLINE style from its own
   bg_colour field, which no stylesheet can beat. Set the field in the editor
   instead — the register's rule: clear the colour in the block, don't fight it
   with CSS. */

/* --------------------------------------------------------------------------
   Type scale
   The tokens set family and colour; they do not set size. Without this the
   whole page renders at body size, which is what a "brand tokens applied but
   nothing looks designed" page looks like.
   -------------------------------------------------------------------------- */

h1{ font-size:clamp(2rem, 4vw, 3rem); line-height:1.15; margin:0 0 .5em; }
h2{ font-size:clamp(1.6rem, 3vw, 2.25rem); line-height:1.2; margin:0 0 .5em; }
h3{ font-size:clamp(1.15rem, 2vw, 1.4rem); line-height:1.3; margin:0 0 .4em; }
p{ margin:0 0 1.1em; line-height:1.65; }

/* --------------------------------------------------------------------------
   Full-bleed sections
   Cambourne runs edge to edge. The theme's <main> constrains its children, so
   alignfull needs the viewport-width escape. HCML and ideate.partners sit in a
   centred container instead — this rule is Cambourne-specific and is exactly
   the kind of thing to check per client.
   -------------------------------------------------------------------------- */

main .alignfull,
main .kb-row-layout-wrap.alignfull{
  width:100vw;
  max-width:100vw;
  margin-left:calc(50% - 50vw);
  margin-right:calc(50% - 50vw);
}

/* --------------------------------------------------------------------------
   Sections over photography
   Applied via the `on-image` class on the Section, NOT via Kadence's
   kt-row-has-bg — that class is added for background *colours* too, so
   targeting it turns white text onto a light background and makes the section
   invisible. Learned the hard way on the values band.
   -------------------------------------------------------------------------- */

.on-image h1, .on-image h2, .on-image h3, .on-image h4, .on-image p, .on-image li{
  color:#ffffff;
}
.on-image a{ color:#ffffff; text-decoration:underline; }

/* Tabs pick up the accent for the active state. */
.baseplate-tab-button.is-active{
  color:var(--accent);
  border-color:var(--accent);
}


/* ==========================================================================
   HOMEPAGE — built to homepage-design-spec.md
   Numbers taken from the design file, not estimated.
   ========================================================================== */

/* --- Hero: min-height 80vh, centred both axes ------------------------------ */
.sec-hero > .kt-row-column-wrap{
  min-height:80vh;
  display:flex;
  align-items:center;
  justify-content:center;
}
.sec-hero .kt-inside-inner-col{ text-align:center; }
.sec-hero h1{
  font-size:clamp(2.4rem, 5.4vw, 4.1rem);
  font-weight:400;
  max-width:13em;
  margin:0 auto;
  text-wrap:balance;
  text-shadow:0 2px 22px rgba(8,20,40,.55);
}

/* --- Intro: heading full width, body in two columns ------------------------ */
.sec-intro h2{ margin-bottom:1.2em; max-width:16em; }
.intro-cols .kt-inside-inner-col{ padding-right:24px; }
.sec-intro p{ font-size:.95rem; }
.hl{ color:var(--accent); font-weight:400; }

/* --- Values: centred, five across -------------------------------------------- */
.sec-values{ text-align:center; }
.sec-values h2{ margin:0 auto 2.6em; }
.value-item .kt-inside-inner-col{ align-items:center; text-align:center; }
.value-item .kb-svg-icon-wrap{
  display:inline-flex; align-items:center; justify-content:center;
  width:52px; height:52px; margin:0 auto .9em;
  border-radius:50%;
  background:rgba(99,147,205,.14);
}
p.v-label{ margin:0 0 .15em; color:var(--ink); font-size:.95rem; }
p.v-sub{ margin:0; color:var(--accent); font-size:.9rem; }

/* --- Testimonial: centred italic serif, small-caps attribution -------------- */
.sec-quote .kt-inside-inner-col{ text-align:center; }
p.q-text{
  font-family:var(--poppins);
  font-style:italic;
  font-size:clamp(1rem, 1.5vw, 1.15rem);
  line-height:1.75;
  max-width:44em;
  margin:0 auto 2em;
}
p.q-attr{
  font-size:.72rem;
  letter-spacing:.18em;
  text-transform:uppercase;
  margin:0;
}

/* --- Responsive, per the spec ---------------------------------------------- */
@media (max-width:1024px){
  .intro-cols .kt-row-column-wrap{ grid-template-columns:1fr; }
  .intro-cols .kt-inside-inner-col{ padding-right:0; }
  .values-row .kt-row-column-wrap{ grid-template-columns:repeat(2,1fr); }
}
@media (max-width:767px){
  .values-row .kt-row-column-wrap{ grid-template-columns:1fr; }
  .sec-hero > .kt-row-column-wrap{ min-height:60vh; }
}


/* --------------------------------------------------------------------------
   Container inside full-bleed sections
   The Section bleeds; its CONTENT does not. This is the two-layer width model:
   background edge to edge, content held to the measure. Without this the copy
   runs to the viewport edges on wide screens.
   -------------------------------------------------------------------------- */

main .alignfull > .kt-row-column-wrap{
  max-width:var(--wrap);
  margin-left:auto;
  margin-right:auto;
  padding-left:28px;
  padding-right:28px;
  box-sizing:border-box;
}

/* Hero is the exception — it is centred flex, full height, no measure. */
.sec-hero > .kt-row-column-wrap{ max-width:none; padding-left:0; padding-right:0; }

/* --- Values: centre each column's content ---------------------------------- */
.values-row .kt-inside-inner-col{
  align-items:center;
  text-align:center;
}
.values-row .wp-block-kadence-icon,
.values-row .kb-svg-icon-wrap{ margin-left:auto; margin-right:auto; }

/* Icon badge — circular pale-blue disc behind the glyph, per the design. */
.values-row .kb-icon-wrap,
.values-row .kt-svg-icon-wrap{
  display:inline-flex; align-items:center; justify-content:center;
  width:52px; height:52px; margin:0 auto 1em;
  border-radius:50%; background:rgba(99,147,205,.14);
}

/* --- Intro: gutter between the two columns --------------------------------- */
.sec-intro-body .kt-row-column-wrap{ column-gap:56px; }
.sec-intro-head h2{ margin-bottom:0; }


/* --------------------------------------------------------------------------
   Over-image text — must out-specify Kadence
   Kadence emits per-block inline <style> keyed to a generated column ID, which
   beats any class selector. These need !important; it is the documented
   exception, same reason the register says not to fight inline colour styles.
   -------------------------------------------------------------------------- */

.on-image h1, .on-image h2, .on-image h3,
.on-image p, .on-image li, .on-image strong, .on-image em{
  color:#ffffff !important;
}



/* --------------------------------------------------------------------------
   Value icon badges
   SVGs are FULLY percent-encoded. Raw < > # in a data: URI render in some
   browsers and silently fail in others — which is exactly what happened here:
   the icons appeared in the editor and were blank on the front end.
   -------------------------------------------------------------------------- */

.values-row .kt-inside-inner-col::before,
.value-item .kt-inside-inner-col::before{
  content:"";
  display:block;
  width:54px; height:54px;
  margin:0 auto 1.1em;
  border-radius:50%;
  background-color:rgba(99,147,205,.14);
  background-repeat:no-repeat;
  background-position:center center;
  background-size:24px 24px;
}
.values-row .wp-block-kadence-icon{ display:none; }

.values-row > .wp-block-kadence-column:nth-child(1) .kt-inside-inner-col::before{
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2724%27%20height%3D%2724%27%20fill%3D%27none%27%20stroke%3D%27%236393cd%27%20stroke-width%3D%271.7%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M3%2018v-6a9%209%200%200%201%2018%200v6%27%2F%3E%3Cpath%20d%3D%27M21%2019a2%202%200%200%201-2%202h-1a2%202%200%200%201-2-2v-3a2%202%200%200%201%202-2h3z%27%2F%3E%3Cpath%20d%3D%27M3%2019a2%202%200%200%200%202%202h1a2%202%200%200%200%202-2v-3a2%202%200%200%200-2-2H3z%27%2F%3E%3C%2Fsvg%3E");
}
.values-row > .wp-block-kadence-column:nth-child(2) .kt-inside-inner-col::before{
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2724%27%20height%3D%2724%27%20fill%3D%27none%27%20stroke%3D%27%236393cd%27%20stroke-width%3D%271.7%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M20.8%204.6a5.5%205.5%200%200%200-7.8%200L12%205.7l-1.1-1.1a5.5%205.5%200%200%200-7.8%207.8l1.1%201.1L12%2021l7.7-7.5%201.1-1.1a5.5%205.5%200%200%200%200-7.8z%27%2F%3E%3C%2Fsvg%3E");
}
.values-row > .wp-block-kadence-column:nth-child(3) .kt-inside-inner-col::before{
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2724%27%20height%3D%2724%27%20fill%3D%27none%27%20stroke%3D%27%236393cd%27%20stroke-width%3D%271.7%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M17%2021v-2a4%204%200%200%200-4-4H5a4%204%200%200%200-4%204v2%27%2F%3E%3Ccircle%20cx%3D%279%27%20cy%3D%277%27%20r%3D%274%27%2F%3E%3Cpath%20d%3D%27M23%2021v-2a4%204%200%200%200-3-3.9%27%2F%3E%3Cpath%20d%3D%27M16%203.1a4%204%200%200%201%200%207.8%27%2F%3E%3C%2Fsvg%3E");
}
.values-row > .wp-block-kadence-column:nth-child(4) .kt-inside-inner-col::before{
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2724%27%20height%3D%2724%27%20fill%3D%27none%27%20stroke%3D%27%236393cd%27%20stroke-width%3D%271.7%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M12%2022s8-4%208-10V5l-8-3-8%203v7c0%206%208%2010%208%2010z%27%2F%3E%3C%2Fsvg%3E");
}
.values-row > .wp-block-kadence-column:nth-child(5) .kt-inside-inner-col::before{
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2724%27%20height%3D%2724%27%20fill%3D%27none%27%20stroke%3D%27%236393cd%27%20stroke-width%3D%271.7%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M20%206%209%2017l-5-5%27%2F%3E%3C%2Fsvg%3E");
}


/* ==========================================================================
   Section-at-root corrections
   The earlier rules targeted .kt-row-column-wrap, which only exists when a
   Row Layout wraps a Section. With Sections at root the inner element is
   .kt-inside-inner-col instead.
   ========================================================================== */

main .alignfull > .kt-inside-inner-col{
  max-width:var(--wrap);
  margin-left:auto; margin-right:auto;
  padding-left:28px; padding-right:28px;
  box-sizing:border-box;
}

/* --- Hero -------------------------------------------------------------------
   Height and darkening are set with Kadence's OWN minHeight and overlay
   attributes on the Section, not in CSS. A CSS ::after overlay on a flex
   Section covered the whole viewport, because the background image sits on an
   inner element rather than on the Section box. Use the block's features.
   -------------------------------------------------------------------------- */
.sec-hero > .kt-inside-inner-col{ max-width:none; width:100%; text-align:center; }
.sec-hero h1{
  font-size:clamp(2.4rem, 5.4vw, 4.1rem);
  font-weight:400;                 /* display serif at 400, not 600 — 600 reads heavy */
  line-height:1.12;
  max-width:13em; margin:0 auto;
  text-wrap:balance;
  text-shadow:0 2px 22px rgba(8,20,40,.55);
}

/* --- Headings generally: lighter weight ------------------------------------ */
h1,h2,h3,h4,
.wp-block-kadence-advancedheading{ font-weight:400; }

/* --- Values: icon badge sizing to match the design ------------------------- */
/* Retired 2026-08-22. This pseudo-element was sized for an icon it was never
   given, so it rendered as a blank square. Icons are now real inline SVG in a
   .v-badge span, as the preview has them. */
.values-row .kt-inside-inner-col::before{ content:none; }
p.v-label{ font-size:.95rem; font-weight:600; letter-spacing:.01em; }
p.v-sub{ font-size:.9rem; font-style:italic; }

/* --- Testimonial: sizing, colour, letter-spacing --------------------------- */
.sec-quote{ position:relative; }
.sec-quote > .kt-inside-inner-col{ position:relative; z-index:2; text-align:center; }
p.q-text{
  font-family:var(--poppins);
  font-style:italic;
  font-weight:400;
  font-size:clamp(1.02rem, 1.35vw, 1.22rem);
  line-height:1.85;
  max-width:42em;
  margin:0 auto 2.2em;
}
p.q-attr{
  font-family:var(--sans);
  font-size:.7rem;
  font-weight:600;
  letter-spacing:.2em;
  text-transform:uppercase;
  margin:0;
}

/* --- Mobile: real breakpoints --------------------------------------------- */
@media (max-width:1024px){
  .intro-cols .kt-row-column-wrap{ grid-template-columns:1fr; }
  .values-row .kt-row-column-wrap{ grid-template-columns:repeat(2,1fr); }
}
@media (max-width:767px){
  .values-row .kt-row-column-wrap{ grid-template-columns:1fr; }
  main .alignfull > .kt-inside-inner-col{ padding-left:20px; padding-right:20px; }
}


/* ==========================================================================
   FULL-BLEED SECTIONS — written against the real markup, not assumed
   Actual structure (read from the rendered page, 2026-08-21):

     <div class="wp-block-kadence-column kadence-column{UID} kb-section-has-overlay
                 alignfull on-image sec-hero">
       <div class="kt-inside-inner-col"> … content … </div>

   Kadence puts the background image and overlay on .kt-inside-inner-col and its
   :before, and generates per-block CSS on .kadence-column{UID}. So height goes
   on the INNER element, and the bleed goes on the OUTER one.
   ========================================================================== */

main .wp-block-kadence-column.alignfull{
  width:100vw;
  max-width:100vw;
  margin-left:calc(50% - 50vw);
  margin-right:calc(50% - 50vw);
  align-self:stretch;
}

/* Content inside a bleeding Section is still held to the measure. */
main .wp-block-kadence-column.alignfull > .kt-inside-inner-col{
  max-width:var(--wrap);
  margin-left:auto;
  margin-right:auto;
  padding-left:28px;
  padding-right:28px;
  box-sizing:border-box;
}

/* --- Hero ------------------------------------------------------------------
   Height belongs on the inner column, because that is the element carrying the
   background. Setting it on the outer box leaves the image in a short band with
   the overlay stretched past it — which is exactly what happened before.
   -------------------------------------------------------------------------- */
.sec-hero > .kt-inside-inner-col{
  min-height:560px;
  max-width:none;
  display:flex;
  flex-direction:column;
  justify-content:center;
  align-items:center;
  text-align:center;
  background-size:cover;
  background-position:center 42%;
}
.sec-hero h1{
  max-width:13em;
  margin:0 auto;
}

@media (max-width:1024px){ .sec-hero > .kt-inside-inner-col{ min-height:460px; } }
@media (max-width:767px){ .sec-hero > .kt-inside-inner-col{ min-height:400px; } }

/* Testimonial also bleeds and centres. */
.sec-quote > .kt-inside-inner-col{ min-height:420px; display:flex; flex-direction:column; justify-content:center; }

/* --------------------------------------------------------------------------
   Image sections must bleed on the INNER element
   Diagnosed from computed styles, 2026-08-21: the Section box was correctly
   1900px, but .kt-inside-inner-col — which is where Kadence paints the
   background image — was capped at var(--wrap). So the photograph rendered at
   1120px inside a full-width section.

   The container rule above must therefore NOT apply to image sections, and the
   selector needs equal-or-greater specificity to win.
   -------------------------------------------------------------------------- */

main .wp-block-kadence-column.alignfull.sec-hero > .kt-inside-inner-col,
main .wp-block-kadence-column.alignfull.sec-quote > .kt-inside-inner-col{
  max-width:none;
  width:100%;
  padding-left:28px;
  padding-right:28px;
}

/* Keep the type itself to a comfortable measure inside those full-width bands. */
.sec-hero h1{ max-width:13em; margin-left:auto; margin-right:auto; }
.sec-quote p.q-text{ max-width:42em; margin-left:auto; margin-right:auto; }

/* ==========================================================================
   6. Pattern library — the section types the homepage did not need
   Added 2026-08-22 for the patterns in `pattern-library.md`. Every class here
   is used by a named pattern in the `cambourne` category. Nothing here styles
   a one-off; if a rule stops being used by a pattern, delete it.

   The two-layer model holds throughout: the Section owns the band, these rules
   only lay out what sits inside it.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Split bands — copy beside an image
   Used by the service-page body and the four team-group bands on Our Team.
   Built as a Kadence Row Layout of two columns inside a Section, so the
   Section keeps the frame.
   -------------------------------------------------------------------------- */

.split-cols > .kt-row-column-wrap{ column-gap:56px; align-items:center; }
.split-cols img{ width:100%; height:auto; display:block; border-radius:var(--radius); }

/* Image-left variant. The pattern sets the order rather than duplicating markup. */
.split-cols.split-reverse > .kt-row-column-wrap > .wp-block-kadence-column:first-child{ order:2; }
.split-cols.split-reverse > .kt-row-column-wrap > .wp-block-kadence-column:last-child{ order:1; }

/* --------------------------------------------------------------------------
   Service-page copy rhythm
   The live pages run kicker → subheading → body → list lead-in → tick list.
   All of it is already in the content; these rules just carry the treatment.
   -------------------------------------------------------------------------- */

.kicker{
  color:var(--accent);
  font-weight:700;
  font-size:.86rem;
  letter-spacing:.02em;
  margin:0 0 .6em;
}

.subhead{
  color:var(--accent);
  font-weight:700;
  font-size:1.05rem;
  margin:0 0 .8em;
}

.list-lead{ color:var(--accent); font-weight:700; margin:1.6em 0 .8em; }

/* --------------------------------------------------------------------------
   Tick list
   Kadence Icon List with the accent check. The icon colour is set on the
   block, so this only handles spacing and the measure.
   -------------------------------------------------------------------------- */

.tick-list .kt-svg-icon-list-item-wrap{ margin-bottom:.55em; color:var(--grey); }
.tick-list .kt-svg-icon-list-single{ color:var(--accent); }

/* --------------------------------------------------------------------------
   Next service band
   Full-bleed accent, small dark label, service name large in the headline
   face, a short rule, then the link. One service, as the live site does it.
   -------------------------------------------------------------------------- */

.sec-next{ background:var(--accent); }
.sec-next .kt-inside-inner-col{ text-align:center; }
/* Simon, 2026-08-23: on the next-service band the LABEL, the hairline and the
   More Info link are all dark blue, and only the service name is white. Every
   service page follows it.

   `--p-color` as well as `color`: `.next-label` is a <p> that is a direct child
   of `.kt-inside-inner-col`, so the @layer theme neutraliser matches it and
   reverts it to HCML's grey unless the property is set. It had been rendering
   #5b6470 grey, not the navy this rule asks for. Caught by measuring the
   computed colour rather than reading the declaration. */
.next-label{
  --p-color:var(--ink);
  color:var(--ink);
  -webkit-text-fill-color:var(--ink);
  font-weight:700;
  font-size:.8rem;
  letter-spacing:.06em;
  text-transform:uppercase;
  margin:0 0 .5em;
}
.next-name{
  font-family:var(--serif);
  color:#fff;
  font-weight:400;
  font-size:clamp(1.8rem,3.4vw,2.8rem);
  line-height:1.15;
  margin:0;
}
.next-rule{
  width:64px;
  height:1px;
  background:var(--ink);
  border:0;
  margin:1.4em auto 1.2em;
}

/* The fill as well as the colour — the same defect as the testimonial quote,
   and a link is exactly the kind of element HCML paints from `@layer base`. */
.next-link a{
  --p-color:var(--ink);
  color:var(--ink);
  -webkit-text-fill-color:var(--ink);
  text-decoration:underline;
  font-weight:600;
}
.sec-next p.next-link{ --p-color:var(--ink); }

/* --------------------------------------------------------------------------
   Contact map — and why it was portrait

   Simon, 2026-08-24: the map was "like a mobile portrait dimension" and had lost
   the white Cambourne info card. Measured: the iframe rendered 300 x 500 inside
   a 1440 band, and its `.kt-inside-inner-col` was 356px — 300 plus 2 x 28 of
   padding.

   Cause, and it is the same family as the testimonial quote running off the
   page: a Kadence Section is a COLUMN flex and `.kt-inside-inner-col` is its
   flex item. A flex item that does not stretch sizes to its content — and an
   <iframe> is a REPLACED element with an intrinsic width of 300px, so the whole
   column shrink-wrapped to it. Ordinary block content fills, which is why no
   other section showed this.

   The embed URL is byte-identical to the live site's, so the missing info card
   was never the URL: Google hides the business card when the map is too narrow.
   One cause, both symptoms.
   -------------------------------------------------------------------------- */

/* The map and the form BOTH shrink-wrapped, for the same reason, and both then
   sat on a different left margin from everything else on the page. Measured at
   1440 before the fix: logo, contact columns and footer all start at 158; the
   map started at 183 and the form at 339. Holding both inner columns to the same
   1180 the contact row above them uses puts all four on 158. */
/* Specificity: the generic measure rule is `main > .wp-block-kadence-column >
   .kt-inside-inner-col`, so a two-class selector loses to it and the map stayed
   at 1130 while the form moved. Match it, and name BOTH roots — `main` does not
   exist in the editor. */
.sec-map > .kt-inside-inner-col,
.sec-form > .kt-inside-inner-col,
main > .wp-block-kadence-column.sec-map > .kt-inside-inner-col,
main > .wp-block-kadence-column.sec-form > .kt-inside-inner-col,
.editor-styles-wrapper .is-root-container > .wp-block-kadence-column.sec-map > .kt-inside-inner-col,
.editor-styles-wrapper .is-root-container > .wp-block-kadence-column.sec-form > .kt-inside-inner-col{
  width:100%;
  max-width:1180px;
  margin-left:auto;
  margin-right:auto;
}

.sec-map iframe{
  display:block;
  width:100%;
  min-height:500px;
  border:0;
}

/* The form itself must fill the column rather than size to its inputs. */
.sec-form form,
.sec-form .wpcf7,
.sec-form .wpcf7-form{ width:100%; max-width:none; }

/* --------------------------------------------------------------------------
   EVERY kit block fills its Section — the one rule that replaces four patches

   A Kadence Section's `.kt-inside-inner-col` is a COLUMN flex, so its child is a
   flex ITEM. A flex item that is not stretched sizes to its CONTENT, and that
   has now caused the same defect four times on this site:

     · the testimonial quote ran off the right of the page
     · the testimonial photograph stopped short of the canvas in the editor
     · the Contact map rendered 300 x 500 portrait, because an <iframe> is a
       REPLACED element with an intrinsic 300px width
     · the Contact form shrank to 818px and sat 181px right of everything else

   Block content usually fills by accident, which is why it only showed up on
   the two sections holding replaced elements. Now that every section on the site
   is one kit block, state it once for all of them.
   -------------------------------------------------------------------------- */

.kt-inside-inner-col > .wp-block-text,
.kt-inside-inner-col > .wp-block-split,
.kt-inside-inner-col > .wp-block-people,
.kt-inside-inner-col > .wp-block-icon-row,
.kt-inside-inner-col > .wp-block-callout,
.kt-inside-inner-col > .wp-block-testimonial,
.kt-inside-inner-col > .wp-block-hero,
.kt-inside-inner-col > .acf-block-preview{
  width:100%;
  max-width:none;
  align-self:stretch;
}

/* --------------------------------------------------------------------------
   Text block — two columns, and the embed slot

   Added 2026-08-24 so the home intro (a heading over two columns of copy) and
   Contact's map and form could stop being loose Kadence markup. The heading
   spans, the copy flows down one column then the next, and an embed sits full
   width beneath. Column gaps match the Row Layout each replaces.
   -------------------------------------------------------------------------- */

.txt-block--cols-2 .txt-block__col{
  columns:2;
  column-gap:48px;
}

/* Never split a paragraph across the column break — it reads as two half
   paragraphs and looks like a fault. */
.txt-block--cols-2 .txt-block__col > *{
  break-inside:avoid;
  page-break-inside:avoid;
}

.txt-block--cols-2 .txt-block__col > *:first-child{ margin-top:0; }

.txt-block__embed{ margin:1.6em 0 0; }

.txt-block__embed iframe{
  display:block;
  width:100%;
  min-height:500px;
  border:0;
}

@media (max-width:900px){
  .txt-block--cols-2 .txt-block__col{ columns:1; }
}

/* --------------------------------------------------------------------------
   Icon row block (acf/icon-row)

   Added 2026-08-24. Replaces two hand-built Kadence Row Layouts — the home
   values row and the Contact details row — with one block in two styles. The
   ITEM markup is unchanged (`v-badge` / `v-label` / `v-sub`, and
   `contact-item--x`), so every rule above still applies and nothing on the page
   moves. Only the grid is new, and it carries the gaps the rows it replaces had:
   values 32px, contact 32/36.
   -------------------------------------------------------------------------- */

.bp-iconrow{
  display:grid;
  column-gap:32px;
  row-gap:36px;
  align-items:start;
}

.bp-iconrow--cols-2{ grid-template-columns:repeat(2, minmax(0, 1fr)); }
.bp-iconrow--cols-3{ grid-template-columns:repeat(3, minmax(0, 1fr)); }
.bp-iconrow--cols-4{ grid-template-columns:repeat(4, minmax(0, 1fr)); }
.bp-iconrow--cols-5{ grid-template-columns:repeat(5, minmax(0, 1fr)); }

.bp-iconrow--badge{ text-align:center; }
.bp-iconrow--details{ text-align:center; }

/* The badge style centres its own items; `.v-badge` already has margin auto. */
.bp-iconrow__item p{ margin-left:auto; margin-right:auto; }

@media (max-width:900px){
  .bp-iconrow--cols-4,
  .bp-iconrow--cols-5{ grid-template-columns:repeat(2, minmax(0, 1fr)); }
}

@media (max-width:600px){
  .bp-iconrow{ grid-template-columns:minmax(0, 1fr) !important; }
}

/* --------------------------------------------------------------------------
   People block (acf/people)

   Added 2026-08-24 so the three hand-built people rows could become one kit
   block. The `.person`, `.person-name`, `.person-role`, `.person-email` and
   `.person-bio` rules already exist above and are reused unchanged — only the
   grid is new. It replaces three Kadence Row Layouts of two columns each, so
   the gaps match what those carried: 48px, 32px under 900.

   No `object-fit` and no `aspect-ratio` on the photograph, deliberately. Setting
   either crops the face out of a square portrait — see trap 27.
   -------------------------------------------------------------------------- */

.bp-people{
  display:grid;
  column-gap:48px;
  row-gap:48px;
  align-items:start;
}

.bp-people--2{ grid-template-columns:repeat(2, minmax(0, 1fr)); }
.bp-people--3{ grid-template-columns:repeat(3, minmax(0, 1fr)); }
.bp-people--4{ grid-template-columns:repeat(4, minmax(0, 1fr)); }

.bp-people .person img{
  display:block;
  width:100%;
  max-width:358px;
  height:auto;
  margin:0 0 1.4em;
  border-radius:0;
}

@media (max-width:900px){
  .bp-people{ column-gap:32px; row-gap:36px; }
  .bp-people--3,
  .bp-people--4{ grid-template-columns:repeat(2, minmax(0, 1fr)); }
}

@media (max-width:600px){
  .bp-people{ grid-template-columns:minmax(0, 1fr) !important; }
}

/* --------------------------------------------------------------------------
   Heading block (acf/heading)

   Added 2026-08-24 so the two heading patterns could become Section + one kit
   block like everything else. Matched to what the Kadence Advanced Heading it
   replaces actually rendered, measured on /our-team/: Source Serif 4, 50px,
   weight 400, --ink, no margin. Both `color` and `--h-color` are set — the
   `@layer theme` neutraliser matches `.wp-block-heading` and would otherwise
   revert this to HCML's, and the block's own heading is not a `.wp-block-heading`
   but the property costs nothing and guards a future change.
   -------------------------------------------------------------------------- */

.bp-heading__title{
  --h-color:var(--ink);
  font-family:var(--serif);
  color:var(--ink);
  font-size:clamp(1.9rem, 3.6vw, 50px);
  font-weight:400;
  line-height:1.15;
  margin:0;
}

.bp-heading__kicker{
  --p-color:var(--accent);
  color:var(--accent);
  -webkit-text-fill-color:var(--accent);
  font-family:var(--sans);
  font-size:.95rem;
  font-weight:700;
  margin:0 0 .6em;
}

.bp-heading--center{ text-align:center; }
.bp-heading--left{ text-align:left; }

/* --------------------------------------------------------------------------
   People row and person card
   Our Team runs these two across. The live page pairs them; a single card in
   the last row is normal and must not be stretched to fill.
   -------------------------------------------------------------------------- */

.people-row > .kt-row-column-wrap{ column-gap:48px; row-gap:48px; align-items:start; }
.person img{ width:100%; height:auto; display:block; border-radius:var(--radius); margin-bottom:1.1em; }
.person-name{
  font-family:var(--serif);
  color:var(--ink);
  font-size:1.25rem;
  font-weight:400;
  margin:0 0 .15em;
}
.person-role{ color:var(--accent); font-weight:600; font-size:.9rem; margin:0 0 .4em; }
.person-email{ font-size:.9rem; margin:0 0 .9em; }
.person-email a{ color:var(--accent); }
.person-bio{ color:var(--grey); font-size:.95rem; margin:0; }

/* --------------------------------------------------------------------------
   Contact details row
   Four equal columns — Address, Phone, E-mail, Fax — as the live page.
   The headings are small, so they are not the page's heading hierarchy.
   -------------------------------------------------------------------------- */

.contact-row > .kt-row-column-wrap{ column-gap:32px; row-gap:36px; }
.contact-row .kt-inside-inner-col{ text-align:center; }
.contact-item h2,
.contact-item h3{
  font-family:var(--sans);
  color:var(--ink);
  font-size:.86rem;
  font-weight:700;
  letter-spacing:.06em;
  text-transform:uppercase;
  margin:0 0 .6em;
}
.contact-item p{ color:var(--grey); font-size:.95rem; margin:0; }
.contact-item a{ color:var(--accent); }

/* --------------------------------------------------------------------------
   Form band
   The consent line is a legal requirement on this site, so it is styled as
   readable copy rather than fine print.
   -------------------------------------------------------------------------- */

.sec-form{ background:var(--mist); }
.sec-form .wpcf7 input[type=text],
.sec-form .wpcf7 input[type=email],
.sec-form .wpcf7 textarea{
  width:100%;
  padding:12px 14px;
  border:1px solid var(--border);
  border-radius:var(--radius);
  font-family:var(--sans);
  font-size:.95rem;
  background:#fff;
}
.sec-form .wpcf7 textarea{ min-height:150px; }
.sec-form .wpcf7 input[type=submit]{
  background:var(--accent);
  color:#fff;
  border:0;
  border-radius:var(--radius);
  padding:12px 28px;
  font-weight:600;
  cursor:pointer;
}
.sec-form .consent{ color:var(--grey); font-size:.9rem; }

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (max-width:900px){
  .split-cols > .kt-row-column-wrap,
  .people-row > .kt-row-column-wrap{ column-gap:32px; }
  .contact-row > .kt-row-column-wrap{ column-gap:24px; }
}

@media (max-width:768px){
  /* Kadence stacks the columns itself; these just tidy what is left. */
  .split-cols.split-reverse > .kt-row-column-wrap > .wp-block-kadence-column:first-child,
  .split-cols.split-reverse > .kt-row-column-wrap > .wp-block-kadence-column:last-child{ order:0; }
  .next-rule{ margin:1.1em auto .9em; }
}

/* --------------------------------------------------------------------------
   Hero block sections
   The Baseplate Hero block manages its own height, padding and measure, so its
   Section must bleed completely and add nothing of its own. Same equal-
   specificity override as the image sections above.
   -------------------------------------------------------------------------- */

main .wp-block-kadence-column.alignfull.sec-hero-block > .kt-inside-inner-col{
  max-width:none;
  width:100%;
  padding-left:0;
  padding-right:0;
}

/* ==========================================================================
   7. Preview treatments — adopted wholesale 2026-08-22
   Simon: "fonts, quote and clarity of quote, icons, header and shading —
   basically all of it looks great and better than the live homepage."
   Values lifted verbatim from cambourne.ideate.partners so the build matches
   the thing that was approved, rather than an approximation of it.

   These REPLACE the flat Kadence overlay used until now. The hero and quote
   patterns set overlayOpacity to 0 so only the scrim below applies; two
   darkening layers stacked is what made the earlier quote hard to read.
   ========================================================================== */

/* --- Hero: a two-layer scrim, not a flat wash ------------------------------ */

.sec-hero,
.sec-hero-block{ position:relative; }

/* ⚠️ The scrim MUST sit on .kt-inside-inner-col, not on the Section box.
   Kadence paints the background image on the inner element, so a scrim on the
   outer box renders BEHIND the photograph and does nothing. This is the same
   trap as section 5b and it caught me twice. Diagnosed by reading computed
   styles, 2026-08-22. */
.sec-hero > .kt-inside-inner-col{ position:relative; }

.sec-hero > .kt-inside-inner-col::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:0;
  pointer-events:none;
  background:
    radial-gradient(120% 80% at 50% 42%, rgba(10,24,46,.05) 0%, rgba(10,24,46,.34) 100%),
    linear-gradient(180deg, rgba(10,24,46,.34) 0%, rgba(10,24,46,.10) 42%, rgba(10,24,46,.40) 100%);
}

.sec-hero > .kt-inside-inner-col > *{ position:relative; z-index:1; }

/* The Hero block carries its own scrim element, so it gets the gradient
   directly rather than a pseudo-element. */
.bp-hero--photo .bp-hero__scrim{
  background:
    radial-gradient(120% 80% at 50% 42%, rgba(10,24,46,.05) 0%, rgba(10,24,46,.34) 100%),
    linear-gradient(180deg, rgba(10,24,46,.34) 0%, rgba(10,24,46,.10) 42%, rgba(10,24,46,.40) 100%);
}

/* --- Quote: the clarity Simon singled out ---------------------------------- */

.sec-quote > .kt-inside-inner-col{ position:relative; }

.sec-quote > .kt-inside-inner-col::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:0;
  pointer-events:none;
  /* Navy rather than the preview's green: the preview's photograph is dark,
     Cambourne's bamboo shot is bright, so the same alpha read far too weak.
     Verified against the rendered page, not assumed. */
  background:linear-gradient(180deg, rgba(10,24,46,.58) 0%, rgba(8,20,40,.78) 100%);
}

.sec-quote > .kt-inside-inner-col > *{ position:relative; z-index:1; }

/* An opening quote mark above the quotation, as the preview has it. */
.sec-quote p.q-text::before{
  content:"\201C";
  display:block;
  font-family:var(--serif);
  font-size:4rem;
  line-height:0;
  height:34px;
  color:rgba(255,255,255,.55);
}

.sec-quote p.q-text{
  font-family:var(--serif);
  font-style:italic;
  font-size:clamp(1.05rem,1.9vw,1.32rem);
  line-height:1.7;
  color:#ffffff;
  text-shadow:0 1px 12px rgba(5,14,28,.55);
  max-width:880px;
}

.sec-quote p.q-attr{
  margin-top:26px;
  font-family:var(--sans);
  font-style:normal;
  letter-spacing:.18em;
  text-transform:uppercase;
  font-size:.74rem;
  color:#e8eef7;
}

/* --- Value items: the circular icon badge --------------------------------- */

.v-badge{
  width:52px;
  height:52px;
  margin:0 auto 18px;
  border-radius:50%;
  background:#eef4fa;
  display:grid;
  place-items:center;
  color:var(--accent);
}

.v-badge svg,
.v-badge .kb-svg-icon-wrap{ width:24px; height:24px; }

p.v-label{
  margin:0;
  font-family:var(--serif);
  font-size:1.16rem;
  font-weight:600;
  color:var(--ink);
  line-height:1.35;
}

p.v-sub{
  display:block;
  margin-top:6px;
  font-family:var(--serif);
  font-style:italic;
  font-weight:500;
  color:var(--accent-deep);
  font-size:.92rem;
  letter-spacing:.04em;
}

/* --- Header: sticky, accent underline on the active item ------------------- */
/* ⬜ The header partial itself is not built yet. These rules are the target,
   lifted from the preview, so the markup can be written against them. */

.site-head{
  position:sticky;
  top:0;
  z-index:40;
  background:rgba(255,255,255,.96);
  backdrop-filter:saturate(140%) blur(6px);
  border-bottom:1px solid var(--border);
}

.site-head .head-inner{
  display:flex;
  align-items:center;
  justify-content:space-between;
  height:80px;
}

.site-head nav.main{ display:flex; align-items:center; gap:30px; }

.site-head nav.main a{
  position:relative;
  font-size:.86rem;
  font-weight:500;
  letter-spacing:.02em;
  color:var(--ink);
}

.site-head nav.main a::after{
  content:"";
  position:absolute;
  left:0;
  bottom:-2px;
  width:0;
  height:2px;
  background:var(--accent);
  transition:width .25s ease;
}

.site-head nav.main a:hover,
.site-head nav.main a.active{ color:var(--accent); }

.site-head nav.main a:hover::after,
.site-head nav.main a.active::after{ width:100%; }

@media (max-width:900px){
  .site-head nav.main{ display:none; }
}

/* --------------------------------------------------------------------------
   Quote text colour — belt and braces
   WordPress global styles emit `:root :where(p){color:...}` inline. It is
   unlayered and not important, so an important author rule beats it, but the
   testimonial has come out dark twice now (sessions 17 and 22). This states it
   at high specificity on the exact elements so there is nothing left to lose to.
   -------------------------------------------------------------------------- */

.sec-quote > .kt-inside-inner-col > p.q-text,
.sec-quote > .kt-inside-inner-col > p.q-attr,
.sec-quote .kt-inside-inner-col p{
  color:#ffffff !important;
}

.sec-quote > .kt-inside-inner-col > p.q-attr{ color:#e8eef7 !important; }

/* ==========================================================================
   8. Full-width canvas — Cambourne is not boxed
   Simon, 2026-08-23: "the main body has grey margins either side. The white
   should be full width, just the text sat in the centre neatly. The whole site
   has no obvious margins left and right visually, but it is controlled so the
   text doesn't flow full width."

   Baseplate inherits HCML's boxed shell from app.css — a grey page background
   with #app capped at 1280px. That is HCML's decision, not a Baseplate default.
   Cambourne runs edge to edge, with the measure held by each Section instead.
   ========================================================================== */

html,
body{ background-color:var(--paper); }

#app{ max-width:none; width:100%; }

#main{ background-color:var(--paper); }

/* --------------------------------------------------------------------------
   Header height
   The preview's header is 80px with the logo left and nav right. The header
   partial itself is still Baseplate's neutral one, so this only sets the frame;
   ⬜ the real header markup is still to build.
   -------------------------------------------------------------------------- */

.site-header,
header.banner{
  min-height:80px;
  display:flex;
  align-items:center;
  background:var(--paper);
  border-bottom:1px solid var(--border);
}

/* The testimonial paragraphs carry an inline colour from the block AND match
   two important rules above, yet computed colour stayed dark — reproduced
   2026-08-23. Setting the fill explicitly as well, since that is what actually
   paints the glyphs. */
.sec-quote .kt-inside-inner-col p,
.sec-quote .kt-inside-inner-col p.q-text,
.sec-quote .kt-inside-inner-col p.q-attr{
  -webkit-text-fill-color:#ffffff !important;
}
.sec-quote .kt-inside-inner-col p.q-attr{ -webkit-text-fill-color:#e8eef7 !important; }

/* ==========================================================================
   9. Header and footer
   Values from the preview. The partials themselves are client-neutral and
   live in Baseplate; everything specific to Cambourne is here or in options.
   ========================================================================== */

/* --- Header ---------------------------------------------------------------- */

.site-head .head-inner{
  max-width:var(--wrap);
  margin:0 auto;
  padding:0 28px;
}

.site-head .brand{ display:flex; align-items:center; text-decoration:none; }
.site-head .brand img{ height:30px; width:auto; display:block; }
.site-head .brand__name{
  font-family:var(--serif);
  font-size:1.3rem;
  color:var(--ink);
  letter-spacing:.01em;
}

.site-head nav.main ul.nav{
  display:flex;
  align-items:center;
  gap:30px;
  list-style:none;
  margin:0;
  padding:0;
}

.site-head nav.main li{ position:relative; margin:0; }
.site-head nav.main a{ text-decoration:none; }
.site-head nav.main .current-menu-item > a{ color:var(--accent); }
.site-head nav.main .current-menu-item > a::after{ width:100%; }

/* Sub-menus, for Our Services */
.site-head nav.main ul.nav ul{
  position:absolute;
  top:100%;
  left:0;
  min-width:280px;
  background:var(--paper);
  border:1px solid var(--border);
  padding:10px 0;
  margin:0;
  list-style:none;
  opacity:0;
  visibility:hidden;
  transition:opacity .18s ease;
  z-index:50;
}
.site-head nav.main li:hover > ul,
.site-head nav.main li:focus-within > ul{ opacity:1; visibility:visible; }
.site-head nav.main ul.nav ul li{ margin:0; }
.site-head nav.main ul.nav ul a{ display:block; padding:8px 20px; font-size:.86rem; }
.site-head nav.main ul.nav ul a::after{ display:none; }

/* Mobile toggle */
.nav-toggle{
  display:none;
  flex-direction:column;
  gap:5px;
  background:none;
  border:0;
  cursor:pointer;
  padding:8px;
}
.nav-toggle span{ display:block; width:24px; height:2px; background:var(--ink); }

/* --------------------------------------------------------------------------
   Mobile navigation — rebuilt 2026-08-24

   ⛔ THE STRUCTURAL BUG, measured at 420px with the menu open: `.site-head` is
   `display:flex; flex-direction:row` — it inherits that from HCML's `app.css`,
   not from this file. So when `.nav-mobile` loses its `hidden` attribute it
   becomes a SECOND FLEX ITEM and lands BESIDE the header bar, not below it.
   The bar took 311px, the menu was squeezed into 153px, every sub-item wrapped
   over three lines, and the document went to **464px wide on a 420px screen**.

   Stacking them is the whole fix for the layout; the rest is making it a decent
   menu — full-width rows, 44px tap targets, and a scroll if it outruns the
   screen, which this one does at twelve items.
   -------------------------------------------------------------------------- */

.site-head.site-header{ display:block; }

.nav-mobile{
  width:100%;
  border-top:1px solid var(--border);
  background:var(--paper);
  max-height:calc(100vh - 80px);
  max-height:calc(100dvh - 80px);   /* dvh accounts for mobile browser chrome */
  overflow-y:auto;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior:contain;
}

.nav-mobile ul.nav{
  list-style:none;
  margin:0;
  padding:4px 28px 20px;
  width:100%;
}

.nav-mobile ul.nav > li{
  margin:0;
  border-bottom:1px solid var(--border);
}

.nav-mobile ul.nav > li:last-child{ border-bottom:0; }

/* Block links with a real tap target — 14px top and bottom on a 1rem line is
   about 46px, over the 44px minimum. */
.nav-mobile a{
  display:block;
  padding:14px 0;
  font-size:1rem;
  line-height:1.3;
  color:var(--ink);
  -webkit-text-fill-color:var(--ink);
  text-decoration:none;
}

.nav-mobile a:hover,
.nav-mobile a:focus-visible{ color:var(--accent); -webkit-text-fill-color:var(--accent); }

/* Sub-items: indented against a rule so the hierarchy reads, and they no longer
   wrap one word per line now the menu has the full width. */
.nav-mobile ul ul{
  list-style:none;
  margin:0 0 10px;
  padding:0 0 0 14px;
  border-left:2px solid var(--border);
}

.nav-mobile ul ul li{ border-bottom:0; margin:0; }

.nav-mobile ul ul a{
  padding:11px 0;
  font-size:.92rem;
  color:var(--grey);
  -webkit-text-fill-color:var(--grey);
}

/* The toggle sits on the right of the bar and needs a real tap target too. */
.nav-toggle{ align-items:center; justify-content:center; min-width:44px; min-height:44px; }

@media (max-width:900px){
  .nav-toggle{ display:flex; }
}

/* --- Footer ---------------------------------------------------------------- */

.site-footer{ background:var(--ink); color:#c7d2e2; }

.site-footer__inner{
  max-width:var(--wrap);
  margin:0 auto;
  padding:0 28px;
}

.site-footer .fgrid{
  display:grid;
  grid-template-columns:1.1fr 1.4fr 1fr;
  gap:48px;
  padding:64px 0 50px;
}

.site-footer .fcol__title{
  font-family:var(--sans);
  text-transform:uppercase;
  letter-spacing:.14em;
  font-size:.74rem;
  font-weight:600;
  color:#fff;
  margin:0 0 18px;
}

.site-footer ul.nav{ list-style:none; margin:0; padding:0; }
.site-footer li{ margin:0 0 11px; }
.site-footer li a{
  font-size:.9rem;
  color:#bcc8da;
  text-decoration:none;
  display:inline-flex;
  gap:8px;
  align-items:baseline;
}
.site-footer li a::before{ content:"\203A"; color:var(--accent); font-size:.9rem; }
.site-footer li a:hover{ color:#fff; }

.site-footer .fcol--contact p{ font-size:.9rem; color:#bcc8da; margin:0 0 10px; line-height:1.7; }

/* Legal bar */
.site-footer__legal{
  border-top:1px solid rgba(255,255,255,.12);
  padding:22px 0 34px;
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:10px 22px;
  font-size:.8rem;
  color:#9fb0c6;
}
.site-footer__legal p{ margin:0; }
.site-footer__legal .legal__nav ul.nav{ display:flex; flex-wrap:wrap; gap:0 22px; }
.site-footer__legal .legal__nav li{ margin:0; }
.site-footer__legal .legal__nav a{ font-size:.8rem; }
.site-footer__legal .legal__nav a::before{ content:none; }

@media (max-width:900px){
  .site-footer .fgrid{ grid-template-columns:1fr; gap:40px; padding:50px 0 40px; }
}

/* --------------------------------------------------------------------------
   Hero copy colour, and the logo
   Same root cause as the testimonial: `color` alone loses on this stack, so
   the fill is set explicitly. Only the photo and split variants sit on a dark
   backdrop; the plain variant keeps the page's own colours.
   -------------------------------------------------------------------------- */

.bp-hero--photo .bp-hero__inner,
.bp-hero--photo .bp-hero__inner *,
.bp-hero--split .bp-hero__inner,
.bp-hero--split .bp-hero__inner *{
  color:#ffffff !important;
  -webkit-text-fill-color:#ffffff !important;
}

.bp-hero__cue{ color:#ffffff !important; -webkit-text-fill-color:transparent !important; }
.bp-hero__cue svg{ stroke:#ffffff; }

/* Logo. An SVG with no intrinsic size renders at 0 unless it is given one. */
.site-head .brand img,
.site-head img.custom-logo,
.site-head .custom-logo-link img{
  height:38px;
  width:auto;
  max-width:220px;
  display:block;
}

.site-head .brand{ flex:0 0 auto; min-width:120px; }
.site-head .head-inner{ gap:24px; }

/* .head-inner is a flex item of .site-head, so it shrink-wraps to its content
   and `margin:0 auto` then centres the whole group. It needs to fill the bar
   for logo-left / nav-right to work. */
.site-head .head-inner{ width:100%; justify-content:space-between; }
.site-head .brand{ display:flex; align-items:center; min-width:0; }

/* Quote sits centred in the band. The max-width set in section 7 dropped the
   auto margins, so the text was centred within a block pushed to the left. */
.sec-quote > .kt-inside-inner-col{ text-align:center; }
.sec-quote p.q-text,
.sec-quote p.q-attr{ margin-left:auto; margin-right:auto; text-align:center; }
.sec-quote p.q-text{ max-width:880px; }

/* --------------------------------------------------------------------------
   Kadence emits a <style> tag alongside each column, inside the row's grid
   container. A grid counts those as items, so a two-column row becomes a
   four-cell grid and the columns land on separate rows — which reads as
   "the layout has stacked for no reason". Take them out of the grid.
   Diagnosed 2026-08-23 by measuring the row's children.
   -------------------------------------------------------------------------- */

.kt-row-column-wrap > style,
.kt-inside-inner-col > style{ display:none !important; }

/* --------------------------------------------------------------------------
   Section gutters at every width
   The measure holds content in on wide screens and Kadence's tablet padding
   takes over below 1024px — but between those two the content box is exactly
   as wide as the viewport and the text sits flush against the screen edge.
   Found at 1100px on 2026-08-23. Targeted by the sec- class so it applies to
   Sections only, never to the columns inside a Row Layout.
   -------------------------------------------------------------------------- */

main .wp-block-kadence-column[class*="sec-"]:not(.sec-hero-block) > .kt-inside-inner-col{
  padding-left:28px;
  padding-right:28px;
}

/* ==========================================================================
   10. Corrections measured against the live site, 2026-08-23
   Every value below was read from cambournefp.co.uk with getComputedStyle
   rather than judged by eye. Simon's snag list, item by item.
   ========================================================================== */

/* --- Service page header colour ---------------------------------------------
   ⚠️ DO NOT hardcode the panel colour here. The Hero block exposes it as a
   field and writes it as --bp-hero-panel, so a blanket CSS rule silently
   overrides EVERY page: it turned the navy headers on Our Team and About Our
   Clients blue, and nothing but looking at them would have shown it.
   The service pages set #6393cd on the block; Team and About set #0c2340.
   ---------------------------------------------------------------------------- */

/* REMOVED 2026-08-24. This rule never applied: an identical-specificity rule
   later in the file (section 23) always won, so this one was dead and merely
   made the file look as though the title alignment was set in two places. Its
   intent — title on the same margin as the body copy — is what the surviving
   rule now does. */

/* --- Body copy lead-ins are bold accent blue, not black ------------------- */
/* `color` alone loses on this stack, so the fill is set too. Same defect as
   the testimonial; see the trap register. */

.kicker,
.subhead,
.list-lead,
.kicker strong,
.subhead strong,
.list-lead strong{
  color:#6393cd !important;
  -webkit-text-fill-color:#6393cd !important;
  font-weight:700;
}

/* --- Next service band is LEFT aligned on the live site ------------------- */

.sec-next .kt-inside-inner-col{ text-align:left; }
.sec-next p.next-label,
.sec-next .next-name,
.sec-next p.next-link{ text-align:left; margin-left:0; margin-right:auto; }
.sec-next .next-rule{ margin-left:0; margin-right:auto; }

/* --- Testimonial is RIGHT aligned on the live site ------------------------ */

.sec-quote > .kt-inside-inner-col{ text-align:right; }
.sec-quote p.q-text,
.sec-quote p.q-attr{ text-align:right; margin-left:auto; margin-right:0; }
.sec-quote p.q-text::before{ text-align:right; }

/* --- Navigation: the accent bar sits ABOVE the item, not under it --------- */
/* Live site uses border-top:3px on the link. */

.site-head nav.main a{
  border-top:3px solid transparent;
  padding-top:8px;
  padding-bottom:8px;
}
.site-head nav.main a::after{ display:none; }
.site-head nav.main a:hover,
.site-head nav.main .current-menu-item > a,
.site-head nav.main .current_page_item > a{ border-top-color:var(--accent); }

/* Quote: the inner column is a flex column. It used to carry `align-items:
   flex-end` to right-justify the loose `<p class="q-text">` paragraphs — but a
   flex item at the cross-end does NOT stretch, it sizes to its content, and
   because this column is deliberately `max-width:none` so the photograph can
   bleed (trap 15), "flex-end" meant the right edge of the BROWSER. The quote ran
   off the page and took the attribution with it. Simon found it, 2026-08-23.

   Those paragraphs no longer exist: all twelve testimonials are `acf/testimonial`
   blocks, and the block right-justifies its own text inside its own 1130px
   measure. So the rule is `stretch`, which is also what makes the photograph
   fill the canvas IN THE EDITOR — there the flex child is the editor's own block
   wrapper, not any element this file could reliably name. One rule, right in
   both places, instead of a rule plus an editor patch. */
.sec-quote > .kt-inside-inner-col{ align-items:stretch; }
.sec-quote > .kt-inside-inner-col > *{ width:100%; max-width:none; }

/* Next service band: hold the inner column to the container and centre it, so
   its left edge lines up with the body copy above. */
.sec-next > .kt-inside-inner-col{
  width:100%;
  max-width:var(--wrap);
  margin-left:auto;
  margin-right:auto;
}

/* The quote band bleeds (its photograph is painted on the inner column), so the
   inner column cannot be capped. Pad it to the container instead, which gives
   the text the same measure as the rest of the page while the photo still runs
   edge to edge. Live site: quote spans 395 to 1505 at a 1900px viewport. */
/* superseded 2026-08-23 — the acf/testimonial block holds its own measure so
   the photograph can reach the screen edge. See section 26. */

/* The earlier alignfull override (section 5b) sets 28px side padding at higher
   specificity, so the container padding above never applied. Match it. */
/* This one was MORE SPECIFIC than the section 19 rule (0,4,1 against 0,3,1),
   so it kept winning and held the photograph 158px in from each edge even
   after section 19 said otherwise. Specificity, not source order, decided it.
   Superseded — the block handles its own measure now. */

/* Contact form: two-column pairs with a full-width message, as the live site.
   Live at 1900px: name/last_name at 385 and 955, each 560 wide; message 1130. */
.sec-form > .kt-inside-inner-col{ max-width:var(--wrap); margin-left:auto; margin-right:auto; }
.sec-form .cf-row{ display:grid; grid-template-columns:1fr 1fr; gap:0 24px; }
.sec-form .cf-row p{ margin:0 0 18px; }
.sec-form label{ display:block; font-size:.85rem; color:var(--ink); }
.sec-form .consent{ display:flex; align-items:flex-start; gap:10px; }
.sec-form .consent .wpcf7-list-item{ margin:0; }

@media (max-width:760px){
  .sec-form .cf-row{ grid-template-columns:1fr; }
}

/* --------------------------------------------------------------------------
   Our Team — measured from the live page 2026-08-23
   Person name is bold accent Open Sans 14px, not a serif navy heading.
   Email link is accent. Photos are square. The Financial Advisors heading is
   Georgia 50px, light weight, LEFT aligned, not centred.
   -------------------------------------------------------------------------- */

p.person-name{
  font-family:var(--sans);
  font-size:.95rem;
  font-weight:700;
  color:#6393cd !important;
  -webkit-text-fill-color:#6393cd !important;
  margin:0 0 .4em;
}

p.person-email{ font-size:.95rem; margin:0 0 1em; }
p.person-email a{ color:#6393cd; }
p.person-bio{ color:var(--grey); font-size:.95rem; margin:0 0 1em; }

.person img{ border-radius:0; }

/* The advisers heading matches the page headings: serif, large, light, left. */
.sec-values.team-heading .kt-inside-inner-col{ text-align:left; }
.sec-values.team-heading h2{
  font-family:var(--serif);
  font-size:clamp(2rem,3.6vw,3.1rem);
  font-weight:300;
  color:var(--ink);
  text-align:left;
  margin:0;
  max-width:none;
}

/* Map band. The live contact page embeds a Google map between the contact
   details and the form. Kept as a named pattern so it is reusable and a client
   can drop it in without touching markup. */
.sec-map iframe{
  display:block;
  width:100%;
  height:500px;
  border:0;
}

/* --------------------------------------------------------------------------
   Split header type and breathing room — measured against the live site
   Live: heading 50px Georgia weight 500; copy ends ~47px short of the panel
   edge. The block's default clamp reached 65.6px at a wide viewport and the
   copy ran to within 32px of the photograph, which read as cramped.
   -------------------------------------------------------------------------- */

.bp-hero--split .bp-hero__heading{
  font-size:clamp(1.9rem, 3.2vw, 3.125rem);   /* 3.125rem = 50px, as live */
  font-weight:500;
  line-height:1.15;
  max-width:none;
}

.bp-hero--split .bp-hero__lede{
  font-size:.95rem;
  max-width:36em;
}

/* Keep the copy clear of the photograph. */
.bp-hero--split .bp-hero__inner{ padding-right:clamp(32px, 4vw, 64px); }

@media (max-width:780px){
  .bp-hero--split .bp-hero__inner{ padding-right:28px; }
}

/* ==========================================================================
   11. Our Team — full element-by-element comparison against the live page
   Measured 2026-08-23 by walking every visible element on both sites rather
   than probing a hand-picked list, which is how these were missed.
   ========================================================================== */

/* Photos are 358px native. Rendering them at 546 upscales and pixelates them.
   Live insets them 56px from the copy, on white. */
.person img{
  max-width:358px;
  width:100%;
  height:auto;
  margin:0 0 1.4em 56px;
  border-radius:0;
  image-rendering:auto;
}

@media (max-width:900px){
  .person img{ margin-left:0; }
}

/* The people rows sit on white, with the grey showing around them. */
.sec-people{ background:transparent; }
.sec-people > .kt-inside-inner-col{ background:var(--paper); }

/* The team-structure bands: live runs 450px columns inside a 1000px measure,
   so the gap between the two sides is generous but not cavernous. Mine were
   546 wide with a 56px gutter, which read as too far apart. */
.sec-team-groups > .kt-inside-inner-col{ max-width:1000px; margin-left:auto; margin-right:auto; }
.sec-team-groups .split-cols > .kt-row-column-wrap{ column-gap:100px; align-items:center; }

/* The statement band above them is grey on the live site, not white. */
/* superseded 2026-08-23 — the band is removed on the block; see section 14
   .sec-team-statement{ background:var(--mist); } */

/* --- Testimonial type: 22px, light, NOT italic ---------------------------- */
/* The preview set it in italics; the live site does not, and at 22px the
   italic serif was also reading small. */
.sec-quote p.q-text{
  font-size:22px;
  font-weight:300;
  font-style:normal;
  line-height:1.6;
}

/* The quote size kept losing to an earlier rule. State it at the same
   specificity as the alignfull overrides so it cannot be overridden again.
   Live: 22px, weight 300, not italic. */
main .wp-block-kadence-column.alignfull.sec-quote p.q-text{
  font-size:22px;
  font-weight:300;
  font-style:normal;
  line-height:1.6;
}
main .wp-block-kadence-column.alignfull.sec-quote p.q-attr{
  font-size:.78rem;
  font-style:normal;
}

/* SUPERSEDED 2026-08-23 — this diagnosis was wrong and is kept only so the
   mistake is not repeated. `:root :where(p)` is NOT !important; it was never
   the cause. The real cause is a cascade layer in the theme — see section 12.
   These unlayered !important rules cannot win and are retained as no-ops. */
main .wp-block-kadence-column.alignfull.sec-quote p.q-text{
  font-size:22px !important;
  line-height:1.6 !important;
}
main .wp-block-kadence-column.alignfull.sec-quote p.q-attr{
  font-size:.78rem !important;
}

/* --------------------------------------------------------------------------
   Nav indicator sits at the TOP OF THE HEADER, not above the text
   On the live site the accent bar runs along the very top edge of the screen
   above the active item. Making the links fill the header height puts their
   top border exactly there.
   -------------------------------------------------------------------------- */

.site-head .head-inner{ align-items:stretch; }
.site-head .brand{ align-items:center; }

.site-head nav.main{ align-items:stretch; }
.site-head nav.main ul.nav{ align-items:stretch; height:100%; }
.site-head nav.main ul.nav > li{ display:flex; align-items:stretch; }

.site-head nav.main ul.nav > li > a{
  display:flex;
  align-items:center;
  height:100%;
  border-top:3px solid transparent;
  padding-top:0;
  padding-bottom:0;
}

.site-head nav.main ul.nav > li > a:hover,
.site-head nav.main ul.nav > li.current-menu-item > a,
.site-head nav.main ul.nav > li.current_page_item > a,
.site-head nav.main ul.nav > li.current-menu-ancestor > a{ border-top-color:var(--accent); }

/* Sub-menu links keep the plain treatment. */
.site-head nav.main ul.nav ul a{ border-top:0; height:auto; }


/* ==========================================================================
   12. THE CASCADE LAYER — why brand CSS kept losing with !important
   Diagnosed 2026-08-23, with a control, after three sessions of guessing.

   Baseplate's compiled app.css carries HCML's blanket rules inside
   `@layer base`:

     @layer base {
       .wp-block-kadence-column .kt-inside-inner-col > p {
         color: rgba(27,27,34,.698) !important;
         font-size: var(--font-size-bodyS) !important;      [resolves to 16px]
         line-height: var(--line-height-bodyS) !important;
         margin: 0 0 16px !important;
       }
       .wp-block-heading { color: rgb(27,22,98) !important; }
     }

   CSS reverses layer order for !important declarations, and UNLAYERED
   !important ranks LOWEST of all. This whole file is unlayered, so every
   !important in it loses to @layer base regardless of specificity, regardless
   of source order. That is why the quote sat at 16px and why its colour
   computed rgba(27,27,34,.698) — the exact value above. The
   -webkit-text-fill-color workaround only ever worked because nothing in the
   layer sets that property.

   app.css declares its layers in the order: properties, theme, base,
   utilities. For !important, EARLIER layers win — so `theme` beats `base`.

   Two rules for anything added here:
     a) `revert-layer` deletes HCML's blanket and lets this file's own cascade
        decide. It does not invent a value.
     b) But `revert-layer !important` is itself layered, so it also beats this
        file's unlayered !important rules. Any value that must survive has to
        be restated INSIDE this layer, at higher specificity than the
        neutraliser. That is why the quote rules are repeated below.
   ========================================================================== */

/* REVISED 2026-08-23, after the first version caused a fault of its own.

   The first version used a bare `revert-layer !important`. That works — but it
   is itself a LAYERED important, so it also beat every unlayered rule in this
   file. Adding an ordinary `.sec-contact-intro p{ font-size:24px }` further
   down silently did nothing, and would have done nothing for every paragraph
   rule written here in future. An invariant that has to be remembered at every
   future edit is not a control — the same lesson as the `kbVersion` stamping
   pass.

   So the layer now defers to custom properties. Custom properties are NOT
   contested by @layer base, so any ORDINARY unlayered rule in this file can set
   `--p-size` / `--p-color` / `--p-lh` / `--p-margin` and win. Where none is set,
   the value falls back to `revert-layer`, which deletes HCML's blanket and
   leaves this file's own cascade to decide.

   Verified in the browser with a control before being written here: a paragraph
   with `--p-size:24px` computes 24px, and one without still computes the brand
   default rather than HCML's. */

@layer theme{
  .wp-block-kadence-column .kt-inside-inner-col > p{
    color:var(--p-color, revert-layer) !important;
    font-size:var(--p-size, revert-layer) !important;
    line-height:var(--p-lh, revert-layer) !important;
    margin:var(--p-margin, revert-layer) !important;
  }

  /* HCML also forces margins from two SEPARATE blanket selectors in the same
     layer, which the rule above does not match. The `p + p` one adds a 16px
     top margin to any paragraph following another — which is what put the
     large gap between "Listening" and "attentively" on the home value items,
     and what no amount of ordinary CSS here could close. */
  .wp-site-blocks p,
  .wp-block-post-content p,
  .entry-content p{
    margin:var(--p-margin, revert-layer) !important;
  }
  .wp-site-blocks p + p,
  .wp-site-blocks .wp-block-heading + p,
  .wp-block-post-content p + p,
  .entry-content p + p{
    margin-top:var(--p-margin-top, revert-layer) !important;
  }
  .wp-block-heading,
  .wp-block-kadence-column .kt-inside-inner-col > .wp-block-heading{
    color:var(--h-color, revert-layer) !important;
    margin:var(--h-margin, revert-layer) !important;
  }
}

/* The testimonial, stated the ordinary way now the layer defers.
   Live: 22px, line-height 27.5px (1.25), weight 300, NOT italic, white. */
main .wp-block-kadence-column.alignfull.sec-quote p.q-text{
  --p-size:22px;
  --p-lh:1.25;
  --p-color:#ffffff;
  font-weight:300;
  font-style:normal;
}
main .wp-block-kadence-column.alignfull.sec-quote p.q-attr{
  --p-size:.78rem;
  --p-color:#e8eef7;
}

/* The decorative opening quote mark is removed. The live site has no separate
   mark — the copy itself begins with a curly quote, so rendering ::before as
   well produced two inverted commas, one stacked above the other. Unlayered
   and last, so it beats the earlier unlayered rule that sets the content. */
.sec-quote p.q-text::before{ content:none !important; display:none !important; }


/* ==========================================================================
   13. Measured against the live site 2026-08-23, page by page
   Every value below was read off the live page at 1440px, not chosen by eye.
   Live reference values are stated so a future change can be checked.
   ========================================================================== */

/* --- Footer text ---------------------------------------------------------
   Live: nav links and contact lines white 14px; the copyright and legal
   links accent #6393cd at 12px. On the build the two legal paragraphs
   computed rgba(27,27,34,.698) — dark grey on navy — because WordPress
   global styles emit `:root :where(p){color:...}`, which beats the footer's
   inherited colour (an inherited value has no specificity; a matching rule
   does). It needs a rule that names the element, not just the container. */

.site-footer p,
.site-footer .legal__line,
.site-footer .legal__reg{ color:#c7d2e2; }

.site-footer .legal__line,
.site-footer .legal__reg{ color:var(--accent); font-size:12px; line-height:1.6; }

.site-footer nav.nav a,
.site-footer ul.nav a{ color:#ffffff; font-size:14px; }

/* --- Testimonial band height ---------------------------------------------
   CORRECTED 2026-08-23. First set to 626px, which was wrong: 626 is the
   height of an oversized background-image layer sitting BEHIND the band. The
   band itself — the navy `mk-video-color-mask` that defines what the reader
   sees — is 500px, on the home page, every service page, Our Team and the
   complaints page alike. Measuring the image layer instead of the painted
   band is the same class of mistake as reading a base64 placeholder as the
   photograph; both are why the band scan now records colour and image
   separately. */

.sec-quote > .kt-inside-inner-col{ min-height:500px; }

main .wp-block-kadence-column.alignfull.sec-quote > .kt-inside-inner-col{
  min-height:500px;
}


/* ==========================================================================
   14. The page background — grey, with white content boxes on it
   Measured 2026-08-23 across all 13 inner pages. EVERY live page paints a
   `master-holder-bg` of #f3f3f3 from just below the header down to the footer,
   and the white areas are content-width boxes sitting ON that grey — they are
   not full-bleed white.

   The build had it inverted: white page, with a couple of grey bands added by
   hand. That is what made the Our Team statement band read as an isolated grey
   stripe, and why the Contact page background was wrong.

   Note this replaces section 8's "Cambourne runs edge to edge, on white". The
   bands still bleed. The page beneath them is grey, as live.
   ========================================================================== */

:root{ --page:#f3f3f3; }

html,
body{ background-color:var(--page); }

#main{ background-color:transparent; }

/* Content sections sit as white boxes on the grey, at their own measure —
   the inner column, never the full-bleed outer Section. */
.sec-people > .kt-inside-inner-col,
.sec-longcopy > .kt-inside-inner-col{
  background:var(--paper);
}

/* CORRECTED 2026-08-23. The service body was first given a white INNER column,
   which produced a 1180px white block with a wide grey margin either side —
   the "white block and grey border" Simon reported. Sampling the live page at
   x=8 down its whole height shows the body is white EDGE TO EDGE: the grey
   holder is never visible on a service page at all. So the Section bleeds and
   the white goes on the OUTER element (trap 15 — Kadence's own background
   field would paint the inner column and could not bleed). The copy inside
   still holds its measure. */
/* superseded 2026-08-23 — no white block; the page grey runs through.
   .sec-service-body{ background:var(--paper); } */

/* NOTE — a blanket `background-color:transparent` on these four was written
   here first and immediately blanked the next-service band's accent, which the
   live site paints #6393cd. Exactly trap 11: a blanket rule wearing a local
   disguise. It was unnecessary anyway — the white was coming from #main, which
   is handled above. Only the form band needs it, because live has no separate
   band there at all. */
.sec-form{ background-color:transparent; }

/* The Our Team statement band. A previous session gave it --mist to separate it
   from a white page. Now the page itself is grey, that mist read as a stray
   stripe — the fault Simon reported. Live has no band here at all: the
   statement sits on the page grey. Fixed by REMOVING the Section's `background`
   attribute, not by overriding it here. */

/* About Our Clients states its opening paragraph in an ACCENT band on the live
   site — #6393cd, 254px — not on white. Measured 2026-08-23.
   The colour must be set HERE, on the outer Section, and NOT on the Kadence
   `background` field — because Kadence paints a Section's background on
   `.kt-inside-inner-col` (trap 4), which is held to the measure. Setting the
   block field produced an accent box 1171px wide inside a band that should
   bleed to 1440. `.sec-next` has always done it this way; this now matches.

   So the rule is narrower than trap 11 says: set it on the block UNLESS the
   block paints it somewhere that cannot bleed. */
.sec-statement-accent{ background:var(--accent); }
.sec-statement-accent p,
.sec-statement-accent .kt-inside-inner-col p{
  --p-color:var(--ink);
  --p-size:30px;
  --p-lh:1.23;
  /* Real declarations as well as the --p-* properties. Those are only read by
     the @layer neutraliser, which matches paragraphs in `main`; in the EDITOR
     that context does not exist, so the size fell back to 16px and the band
     looked nothing like the front end. Simon spotted it in the editor. */
  color:var(--ink);
  font-size:30px;
  line-height:1.23;
  -webkit-text-fill-color:var(--ink);
  font-style:italic;
  font-family:var(--serif);
  font-weight:400;
  text-align:left;
  max-width:1012px;
}

@media (max-width:900px){
  .sec-statement-accent p,
  .sec-statement-accent .kt-inside-inner-col p{
    --p-size:clamp(1.15rem, 3.4vw, 30px);
    font-size:clamp(1.15rem, 3.4vw, 30px);
  }
}


/* ==========================================================================
   15. Contact details icons
   The live page puts a 40px accent icon above each of the four labels —
   map-marker, phone, envelope-open, fax, all #6393cd. The build had none:
   pattern 19 was specified as "Row Layout 4 col — Address, Phone, E-mail, Fax"
   and no icon was ever in the spec, so no check could miss it — there was
   nothing to compare against.

   Live draws these as FontAwesome font glyphs in a `::before`, i.e. as
   decoration rather than content, so this reproduces the same mechanism. The
   path data is Kadence's own copy of FontAwesome Free (CC BY 4.0), so the
   shapes match the live site exactly. Each icon is keyed to a modifier class
   set ON THE BLOCK — not to :nth-child — so reordering the columns cannot
   silently reassign them.

   Drawn with mask-image rather than a coloured background so the colour comes
   from `--accent` and follows any palette decision.
   ========================================================================== */

.contact-item--address .kt-inside-inner-col,
.contact-item--phone .kt-inside-inner-col,
.contact-item--email .kt-inside-inner-col,
.contact-item--fax .kt-inside-inner-col{ position:relative; }

.contact-item--address::before,
.contact-item--phone::before,
.contact-item--email::before,
.contact-item--fax::before{
  content:"";
  display:block;
  width:40px;
  height:40px;
  margin:0 0 18px;
  background-color:var(--accent);
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-position:left center; mask-position:left center;
  -webkit-mask-size:contain; mask-size:contain;
}

.contact-item--address::before{ -webkit-mask-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20384%20512%22%3E%3Cpath%20fill%3D%22%2523000%22%20d%3D%22M172.268%20501.67C26.97%20291.031%200%20269.413%200%20192%200%2085.961%2085.961%200%20192%200s192%2085.961%20192%20192c0%2077.413-26.97%2099.031-172.268%20309.67-9.535%2013.774-29.93%2013.773-39.464%200z%22%2F%3E%3C%2Fsvg%3E"); mask-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20384%20512%22%3E%3Cpath%20fill%3D%22%2523000%22%20d%3D%22M172.268%20501.67C26.97%20291.031%200%20269.413%200%20192%200%2085.961%2085.961%200%20192%200s192%2085.961%20192%20192c0%2077.413-26.97%2099.031-172.268%20309.67-9.535%2013.774-29.93%2013.773-39.464%200z%22%2F%3E%3C%2Fsvg%3E"); }
.contact-item--phone::before{ -webkit-mask-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20512%20512%22%3E%3Cpath%20fill%3D%22%2523000%22%20d%3D%22M493.4%2024.6l-104-24c-11.3-2.6-22.9%203.3-27.5%2013.9l-48%20112c-4.2%209.8-1.4%2021.3%206.9%2028l60.6%2049.6c-36%2076.7-98.9%20140.5-177.2%20177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112%2048C3.9%20366.5-2%20378.1.6%20389.4l24%20104C27.1%20504.2%2036.7%20512%2048%20512c256.1%200%20464-207.5%20464-464%200-11.2-7.7-20.9-18.6-23.4z%22%2F%3E%3C%2Fsvg%3E"); mask-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20512%20512%22%3E%3Cpath%20fill%3D%22%2523000%22%20d%3D%22M493.4%2024.6l-104-24c-11.3-2.6-22.9%203.3-27.5%2013.9l-48%20112c-4.2%209.8-1.4%2021.3%206.9%2028l60.6%2049.6c-36%2076.7-98.9%20140.5-177.2%20177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112%2048C3.9%20366.5-2%20378.1.6%20389.4l24%20104C27.1%20504.2%2036.7%20512%2048%20512c256.1%200%20464-207.5%20464-464%200-11.2-7.7-20.9-18.6-23.4z%22%2F%3E%3C%2Fsvg%3E"); }
.contact-item--email::before{ -webkit-mask-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20512%20512%22%3E%3Cpath%20fill%3D%22%2523000%22%20d%3D%22M512%20464c0%2026.51-21.49%2048-48%2048H48c-26.51%200-48-21.49-48-48V200.724a48%2048%200%200%201%2018.387-37.776c24.913-19.529%2045.501-35.365%20164.2-121.511C199.412%2029.17%20232.797-.347%20256%20.003c23.198-.354%2056.596%2029.172%2073.413%2041.433%20118.687%2086.137%20139.303%20101.995%20164.2%20121.512A48%2048%200%200%201%20512%20200.724V464zm-65.666-196.605c-2.563-3.728-7.7-4.595-11.339-1.907-22.845%2016.873-55.462%2040.705-105.582%2077.079-16.825%2012.266-50.21%2041.781-73.413%2041.43-23.211.344-56.559-29.143-73.413-41.43-50.114-36.37-82.734-60.204-105.582-77.079-3.639-2.688-8.776-1.821-11.339%201.907l-9.072%2013.196a7.998%207.998%200%200%200%201.839%2010.967c22.887%2016.899%2055.454%2040.69%20105.303%2076.868%2020.274%2014.781%2056.524%2047.813%2092.264%2047.573%2035.724.242%2071.961-32.771%2092.263-47.573%2049.85-36.179%2082.418-59.97%20105.303-76.868a7.998%207.998%200%200%200%201.839-10.967l-9.071-13.196z%22%2F%3E%3C%2Fsvg%3E"); mask-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20512%20512%22%3E%3Cpath%20fill%3D%22%2523000%22%20d%3D%22M512%20464c0%2026.51-21.49%2048-48%2048H48c-26.51%200-48-21.49-48-48V200.724a48%2048%200%200%201%2018.387-37.776c24.913-19.529%2045.501-35.365%20164.2-121.511C199.412%2029.17%20232.797-.347%20256%20.003c23.198-.354%2056.596%2029.172%2073.413%2041.433%20118.687%2086.137%20139.303%20101.995%20164.2%20121.512A48%2048%200%200%201%20512%20200.724V464zm-65.666-196.605c-2.563-3.728-7.7-4.595-11.339-1.907-22.845%2016.873-55.462%2040.705-105.582%2077.079-16.825%2012.266-50.21%2041.781-73.413%2041.43-23.211.344-56.559-29.143-73.413-41.43-50.114-36.37-82.734-60.204-105.582-77.079-3.639-2.688-8.776-1.821-11.339%201.907l-9.072%2013.196a7.998%207.998%200%200%200%201.839%2010.967c22.887%2016.899%2055.454%2040.69%20105.303%2076.868%2020.274%2014.781%2056.524%2047.813%2092.264%2047.573%2035.724.242%2071.961-32.771%2092.263-47.573%2049.85-36.179%2082.418-59.97%20105.303-76.868a7.998%207.998%200%200%200%201.839-10.967l-9.071-13.196z%22%2F%3E%3C%2Fsvg%3E"); }
.contact-item--fax::before{ -webkit-mask-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20512%20512%22%3E%3Cpath%20fill%3D%22%2523000%22%20d%3D%22M128%20144v320c0%2026.51-21.49%2048-48%2048H48c-26.51%200-48-21.49-48-48V144c0-26.51%2021.49-48%2048-48h32c26.51%200%2048%2021.49%2048%2048zm384%2064v256c0%2026.51-21.49%2048-48%2048H192c-26.51%200-48-21.49-48-48V40c0-22.091%2017.909-40%2040-40h207.432a39.996%2039.996%200%200%201%2028.284%2011.716l48.569%2048.569A39.999%2039.999%200%200%201%20480%2088.568v74.174c18.641%206.591%2032%2024.36%2032%2045.258zm-320-16h240V96h-24c-13.203%200-24-10.797-24-24V48H192v144zm96%20204c0-6.627-5.373-12-12-12h-40c-6.627%200-12%205.373-12%2012v40c0%206.627%205.373%2012%2012%2012h40c6.627%200%2012-5.373%2012-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627%200-12%205.373-12%2012v40c0%206.627%205.373%2012%2012%2012h40c6.627%200%2012-5.373%2012-12v-40zm128%20128c0-6.627-5.373-12-12-12h-40c-6.627%200-12%205.373-12%2012v40c0%206.627%205.373%2012%2012%2012h40c6.627%200%2012-5.373%2012-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627%200-12%205.373-12%2012v40c0%206.627%205.373%2012%2012%2012h40c6.627%200%2012-5.373%2012-12v-40z%22%2F%3E%3C%2Fsvg%3E"); mask-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20512%20512%22%3E%3Cpath%20fill%3D%22%2523000%22%20d%3D%22M128%20144v320c0%2026.51-21.49%2048-48%2048H48c-26.51%200-48-21.49-48-48V144c0-26.51%2021.49-48%2048-48h32c26.51%200%2048%2021.49%2048%2048zm384%2064v256c0%2026.51-21.49%2048-48%2048H192c-26.51%200-48-21.49-48-48V40c0-22.091%2017.909-40%2040-40h207.432a39.996%2039.996%200%200%201%2028.284%2011.716l48.569%2048.569A39.999%2039.999%200%200%201%20480%2088.568v74.174c18.641%206.591%2032%2024.36%2032%2045.258zm-320-16h240V96h-24c-13.203%200-24-10.797-24-24V48H192v144zm96%20204c0-6.627-5.373-12-12-12h-40c-6.627%200-12%205.373-12%2012v40c0%206.627%205.373%2012%2012%2012h40c6.627%200%2012-5.373%2012-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627%200-12%205.373-12%2012v40c0%206.627%205.373%2012%2012%2012h40c6.627%200%2012-5.373%2012-12v-40zm128%20128c0-6.627-5.373-12-12-12h-40c-6.627%200-12%205.373-12%2012v40c0%206.627%205.373%2012%2012%2012h40c6.627%200%2012-5.373%2012-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627%200-12%205.373-12%2012v40c0%206.627%205.373%2012%2012%2012h40c6.627%200%2012-5.373%2012-12v-40z%22%2F%3E%3C%2Fsvg%3E"); }


/* ==========================================================================
   16. Home page — measured against the live page 2026-08-23
   Sampling the live home page at x=8 down its full height gives: dark hero to
   y≈1000, then WHITE edge to edge for the intro and values, then the navy
   testimonial. There is no grey margin anywhere on it.

   The build had `background:#ffffff` set on the Kadence Section field for both
   content bands, which paints `.kt-inside-inner-col` (trap 15) — so the white
   stopped at the 1180 measure and the page grey showed either side as a
   border. Same fault, same cause, as the service pages.

   ⬜ SIMON: live is WHITE here and you asked for grey. This makes it match live
   and removes the white-block-with-grey-border artefact either way. If you want
   grey instead, it is one line — change --paper to --page below.
   ========================================================================== */

.sec-page-white{ background:transparent; }   /* see section 19 — live home is grey here */

/* The second heading. Live: Georgia 55px, weight 400, accent #6393cd, LEFT,
   and it spans the full 1110 measure above the two columns. The build had it at
   36px navy and 576px wide — 576px because `.sec-intro h2` carries
   `max-width:16em`, which at 36px is exactly 576. It was never a column
   problem: the heading is already a sibling above the Row Layout. */

.sec-intro.sec-page-white h2{
  max-width:none;
  font-size:55px;
  font-weight:400;
  /* CORRECTED. This was set to --accent from a reading of the <h2>'s own
     colour. The <h2> does compute #6393cd on the live page — but the glyphs
     are painted by a <span> INSIDE it, and that span is #000000. Reading the
     wrapper instead of the element that paints is the same mistake that made
     the page background wrong twice. Live renders BLACK. */
  color:#000000;
  text-align:left;
  line-height:1.15;
  margin-bottom:40px;      /* live leaves ~54px to the copy beneath */
}

@media (max-width:900px){
  .sec-intro.sec-page-white h2{ font-size:clamp(2rem, 6vw, 55px); }
}


/* ==========================================================================
   17. Contact Us — measured against the live page 2026-08-23
   Every value read off the live page at 1440px.

                        live                          build (before)
   "Get In Touch"       Georgia 55px/400 navy CENTRED  left, smaller
   standfirst           Georgia 24px/400 CENTRED       left, 16px
   labels               Georgia 25px/500 navy LEFT     13.76px BOLD UPPERCASE,
                                                       letter-spaced, CENTRED
   values               Open Sans 17px/400 LEFT        15.2px CENTRED
   icons                40px accent, LEFT              (absent)

   The labels were being set as small uppercase eyebrows — a reasonable design
   choice, but not this design. The whole row was centred while the icons sat
   left, which is the mismatch that made it read as out of sync.
   ========================================================================== */

/* The row is LEFT aligned on live, not centred. */
.contact-row .kt-inside-inner-col{ text-align:left; }
.contact-row > .kt-row-column-wrap{ column-gap:32px; row-gap:36px; }

.contact-item h2,
.contact-item h3{
  font-family:var(--serif);
  color:var(--ink);
  font-size:25px;
  font-weight:500;
  line-height:1;
  letter-spacing:normal;
  text-transform:none;
  text-align:left;
  margin:0 0 .55em;
}

.contact-item p{
  --p-color:var(--grey);
  --p-size:17px;
  --p-lh:1.37;
  --p-margin:0;
  text-align:left;
}
.contact-item a{ color:var(--accent); }

/* "Get In Touch" and its standfirst are centred on live. Scoped to the class
   on the Contact page's Section so About and Our Team are untouched. */
.sec-contact-intro > .kt-inside-inner-col{ text-align:center; }

.sec-contact-intro h1,
.sec-contact-intro h2{
  font-family:var(--serif);
  font-size:55px;
  font-weight:400;
  line-height:1.5;
  color:var(--ink);
  text-align:center;
  max-width:none;
  margin:0 0 .35em;
}

.sec-contact-intro p{
  --p-size:24px;
  --p-lh:1.2;
  --p-color:var(--grey);
  font-family:var(--serif);
  font-weight:400;
  text-align:center;
  max-width:none;
  margin-left:auto;
  margin-right:auto;
}

@media (max-width:900px){
  .sec-contact-intro h1,
  .sec-contact-intro h2{ font-size:clamp(2rem, 6vw, 55px); }
  .sec-contact-intro p{ --p-size:clamp(1.05rem, 3vw, 24px); }
}


/* ==========================================================================
   18. Declared weight is not rendered weight when the family changes
   Measured 2026-08-23 on Our Team and About Our Clients.

   The live site declares `font-weight:300` on the "Financial Advisors" heading
   and `font-weight:100` on the About statement. **Georgia has no light weights
   at all** — only regular and bold — so a browser resolves both of those to
   Georgia Regular. The live page therefore RENDERS at 400 no matter what its
   CSS says.

   Source Serif 4 is a variable font with real light weights, so copying the
   declared 300 or 100 across produced type that is genuinely, visibly thinner
   than the site it is meant to match. That is the "text is thin" Simon
   reported, and it is why comparing the declared value passes while the page
   still looks wrong.

   **The rule: when the typeface changes, match the RENDERED weight, not the
   declared one.** Check what weights the reference family actually ships.
   ========================================================================== */

.sec-values.team-heading h2{
  font-weight:400;
  font-size:50px;          /* live is exactly 50px; the clamp capped it at 49.6 */
  line-height:1;           /* live line-height is 50px on a 50px heading */
}

@media (max-width:900px){
  .sec-values.team-heading h2{ font-size:clamp(2rem, 5.5vw, 50px); }
}

/* Live: Georgia 24px/500 on the team-structure band headings. Source Serif has
   a true 500, so this one transfers unchanged — recorded so the next person
   does not "correct" it to match the pattern above. */
.sec-team-groups h3{ font-weight:500; font-size:24px; }


/* ==========================================================================
   19. THE MEASURE — every band bleeds, the copy inside holds 1130
   REWRITTEN 2026-08-23 (third time; the history matters, so it is kept short).

     v1  everything full-bleed          -> white block with grey borders
     v2  everything boxed to 1130       -> broke the split hero, and left the
                                           service pages looking like framed
                                           panels floating on grey
     v3  BANDS BLEED, COPY IS CONTAINED <- this. Simon, 2026-08-23:
         "the white block needs to go, so it's all grey background. The light
          blue next service background needs to be full width, as does the
          image with a quote set above it... the text and the image next to it
          is in the right place, aligned perfectly with next service below."

   So: the Section spans the viewport, its inner column holds 1130 centred, and
   nothing paints a box around the copy. This is the two-layer model the pattern
   library described from the start.

   NOTE this diverges from live, which boxes its bands — measured from pixels,
   recorded so nobody "corrects" it back. It matches the preview language and
   Simon's instruction, which is the design authority here.

   The 15px inner padding is deliberate: it keeps the copy at exactly the x it
   already sits at (170 to 1270 at 1440), which Simon confirmed is correct.
   ========================================================================== */

/* THE ROOT. On the front end Sections are children of <main>. In the editor
   they are children of the block list's root container — `main` does not exist
   there at all, which is why NONE of these rules reached the editor and the
   bands came out at unrelated widths. Both roots are named on every rule now. */

main > .wp-block-kadence-column,
main > .wp-block-kadence-column.alignfull{
  width:100vw;
  max-width:100vw;
  margin-left:calc(50% - 50vw);
  margin-right:calc(50% - 50vw);
}

/* In the editor the canvas IS the page, so "full bleed" means filling the
   canvas. Using 100vw here would overflow it by the width of the sidebar. */
.editor-styles-wrapper .is-root-container > .wp-block-kadence-column,
.editor-styles-wrapper .block-editor-block-list__layout.is-root-container > .wp-block-kadence-column{
  width:auto;
  max-width:none;
  margin-left:0;
  margin-right:0;
}

main > .wp-block-kadence-column > .kt-inside-inner-col,
.editor-styles-wrapper .is-root-container > .wp-block-kadence-column > .kt-inside-inner-col{
  max-width:1130px;
  margin-left:auto;
  margin-right:auto;
  padding-left:15px;
  padding-right:15px;
}

/* TWO EXCEPTIONS, and both exist for the same reason: these inner columns
   PAINT something that must reach the screen edge, so they cannot be capped.
   Kadence puts a Section's background image on `.kt-inside-inner-col`
   (trap 4), and the Hero block builds its panel and photo inside it. Cap
   either one and the artwork stops at 1130. Pad instead of capping. */

main > .wp-block-kadence-column.sec-hero-block > .kt-inside-inner-col,
.editor-styles-wrapper .is-root-container > .wp-block-kadence-column.sec-hero-block > .kt-inside-inner-col{
  max-width:none;
  padding-left:0;
  padding-right:0;
}

/* `100%` here, not `100vw`. The element IS the full-bleed band, so on the front
   end the two are identical — but 100% is also correct in the editor, where
   100vw is the browser window and threw the quote's attribution off the end.
   One rule, right in both places, instead of a rule plus an editor patch. */
main .wp-block-kadence-column.alignfull.sec-quote > .kt-inside-inner-col,
main > .wp-block-kadence-column.sec-quote > .kt-inside-inner-col,
.editor-styles-wrapper .is-root-container > .wp-block-kadence-column.sec-quote > .kt-inside-inner-col{
  max-width:none;
  padding:0;
}

/* The service body carries no white block any more — the page grey runs
   through it, as Simon asked. Our Team keeps its white people cards, which
   live also has, so that rule stays. */
.sec-people > .kt-inside-inner-col{
  max-width:1100px;
  margin-left:auto;
  margin-right:auto;
}

@media (max-width:1180px){
  main > .wp-block-kadence-column > .kt-inside-inner-col{
    padding-left:28px;
    padding-right:28px;
  }
}

/* ==========================================================================
   20. Home value items — the label and its sub-label belong together
   The pair reads as one phrase ("Listening / attentively"), so the gap between
   them should be smaller than the gap to the next item, not larger. It was
   16px top + 16px bottom because of HCML's `p + p` rule in @layer base, now
   neutralised in section 12.
   ========================================================================== */

p.v-label{
  --p-margin:0;
  --p-margin-top:0;
  --p-color:var(--ink);
  font-weight:600;
  line-height:1.25;
}

p.v-sub{
  --p-margin:0;
  --p-margin-top:2px;
  --p-color:var(--accent);
  font-style:italic;
  line-height:1.25;
}

/* ==========================================================================
   21. The block editor
   Two things go wrong in the editor that cannot go wrong on the front end:

   1. `vw` units resolve against the BROWSER WINDOW, not the editor canvas. A
      heading sized in vw is therefore set for a 2000px screen while sitting in
      a 650px canvas column, so it wraps one word per line.
   2. The split hero puts a half-width panel inside an already-narrow canvas,
      leaving a very narrow column for a 50px heading.

   These rules are EDITOR-ONLY: `.editor-styles-wrapper` exists only there, so
   nothing here can reach the front end. The aim is a preview a client can read
   and edit confidently — not a pixel match to the front end, which a narrower
   canvas cannot give.
   ========================================================================== */

/* REVISED 2026-08-23. The first version set `.bp-hero--split{display:block}` to
   stack the panel and the photo, because the heading was wrapping one word per
   line. That was treating the symptom: the real cause was the `100vw` padding
   (trap 18 / section 23), and stacking merely hid it while making the editor
   look nothing like the front end.

   With the padding fixed, the split renders side by side here exactly as it
   does on the front end. All that is still needed is to replace anything sized
   in `vw`, because in the editor `vw` is the BROWSER WINDOW, not the canvas —
   at a 2000px window the hero's padding computed 480px inside a ~640px panel
   and shoved the copy to the right. */

/* The same formula in the editor, so the canvas matches the front end. It was a
   flat 45px, which meant the editor and the front end disagreed by design. */
.editor-styles-wrapper .bp-hero--split .bp-hero__inner{
  padding-left:max(28px, calc(100% - var(--wrap) / 2 + 28px));
  padding-right:clamp(28px, 4vw, 64px);
}

/* Fixed sizes: vw is meaningless against a canvas narrower than the window. */
/* Specific enough to beat `.bp-hero--split .bp-hero__heading`, which carries a
   vw clamp at the same specificity — relying on source order alone would break
   the moment anything is appended below. */
.editor-styles-wrapper .bp-hero--split .bp-hero__heading,
.editor-styles-wrapper .bp-hero .bp-hero__heading{ font-size:44px; line-height:1.15; }
.editor-styles-wrapper .bp-hero .bp-hero__lede{ font-size:15px; }


/* ==========================================================================
   22. Home value items — badge contrast and the gap under the heading
   Both measured 2026-08-23 after Simon flagged them.

   THE BADGE. It was #eef4fa, chosen when the page behind it was WHITE. Once
   section 19 made the page grey #f3f3f3, the two became indistinguishable:

       #eef4fa on #f3f3f3  =  contrast ratio 1.00

   1.00 is not "low contrast" — it is identical relative luminance. The disc was
   invisible. Worth recording as a general point: a tint picked against one
   background does not survive a change of background, and nothing in the build
   checks would have caught it, because both colours were individually "correct".

       #ccdcf0 on #f3f3f3  =  1.26   (a clear but still soft disc)
       #6393cd on #ccdcf0  =  2.29   (the accent glyph still reads on its disc)

   THE GAP. `.sec-values h2` carried `margin-bottom:2.6em`, which at the home
   heading's 36px is 93.6px — the icons sat almost 100px below their own
   heading. Reduced to 48px. Scoped to the home section so the Our Team heading,
   which uses the same `.sec-values` class at 50px, is not touched.
   ========================================================================== */

.v-badge{ background:#ccdcf0; }

.sec-values.sec-page-white h2{ margin-bottom:48px; }


/* ==========================================================================
   23. Fixing what section 19 broke — paddings that assumed a full-bleed band
   Found 2026-08-23 when Simon looked at Our Team and the hero was unreadable.

   Three rules in this file centred their copy on the page measure with

       padding-left: max(28px, calc((100vw - var(--wrap)) / 2 + 28px))

   That is correct ONLY while the element spans the viewport: it pushes the copy
   in from the screen edge to line up with the 1180 measure. At 1440 it computes
   158px.

   Section 19 then boxed every band to 1130. The calculation kept using 100vw,
   so a 565px hero panel got a 158px left inset and the heading was left with
   349px — one or two words per line. The same 158px was being applied to the
   testimonial's inner column.

   I changed the geometry and did not re-check the rules that depended on it.
   Worse, my checks could not have caught it: I was sampling band COLOURS and
   comparing type metrics, and both still matched. Nothing was looking at
   whether the page was READABLE. That is now tools/page_shots.js.

   Live, measured on Our Team at 1440:
     hero heading   x=200 — about 45px in from the panel's left edge
     hero lede      x=200, same margin
     quote          x=165 to 1275, i.e. it fills the content column
   ========================================================================== */

/* The hero bleeds again (section 19, revised), so its copy must line up with
   the 1130 content column below it — not sit a flat gutter in from the screen
   edge. Centre on 1130, then the same 45px inset live uses.

     1440 viewport -> (1440-1130)/2 + 45 = 200px   <- live's heading x is 200
     2000 viewport -> (2000-1130)/2 + 45 = 480px   <- column starts 435, so 45 in

   Centring on --wrap (1180) instead of 1130 is what produced the 158px bite
   earlier; the number has to be the column the page actually uses. */
/* The copy lines up with the 1130 column. Expressed against the PANEL's own
   width rather than the viewport, so it is correct in the editor too:

     panel = half the band, so column-left = panel - 565, plus live's 45px
     -> padding-left = panel - 520

     panel 720 (1440 viewport) -> 200   <- live's heading x is 200
     panel 1000 (2000 viewport) -> 480  <- column starts 435, so 45px in

   The old form used 100vw and was the single most expensive rule of the day:
   it survived the band being boxed, took 158px out of a 565px panel, and made
   the heading wrap one word per line. */
/* CHANGED 2026-08-24, Simon: the page title must sit on the SAME left margin as
   the logo and the body copy, not on live's own indent. This is a deliberate
   departure from live — measured, live puts the heading at 200px while the body
   column starts at 158px, and the heading looked indented against everything
   else on the page.

   Still expressed against the PANEL's own width, never `vw` (trap 18): the panel
   is half the band, so the body column's left edge is `panel - wrap/2 + 28`.
   Verified against the rendered body copy at two viewports:

     panel  720 (1440 viewport) -> 158   body copy measured at 158
     panel 1000 (2000 viewport) -> 438   body copy measured at 438 */
.bp-hero--split .bp-hero__inner{
  padding-left:max(28px, calc(100% - var(--wrap) / 2 + 28px));
  padding-right:clamp(28px, 4vw, 64px);
}

/* superseded by section 19's quote exception, which pads to the measure while
   letting the photograph reach the screen edge. */

/* The two pages whose bands genuinely still bleed (section 19) DO need the copy
   centred on the measure, because there the band really does span the viewport. */
/* superseded 2026-08-23 — see section 26; the block holds its own measure.
   Worth noting how this survived two attempts to remove it: the replacements
   were written as `main >` while the file said `main ` (a descendant, not a
   child). A text replace that does not match fails SILENTLY, so the rule stayed
   and kept the photograph 158px in from each edge. Grep for the selector, do
   not assume the edit landed. */

@media (max-width:1180px){
  .bp-hero--split .bp-hero__inner{ padding-left:28px; padding-right:28px; }
}


/* ==========================================================================
   24. Person cards — the job title belongs on its own line
   Simon, 2026-08-23. The build had name, qualification and role run together
   in one paragraph: "Mark Adams ( DipPFS) Managing Director & Financial
   Planner". Live sets them as two lines, both accent bold:

       Mark Adams (DipPFS)
       Managing Director & Financial Planner

       markadams@cambournefp.co.uk

       Mark began his career in Financial Services in 1983...

   The page content is now split into `person-name` and `person-role`
   paragraphs (and the stray space in "( DipPFS)" is gone). Sizes go through
   --p-* so they survive the @layer neutraliser — see section 12.

   Live, measured: name and role both 14px / 700 / #6393cd; email 14px / 400.
   ========================================================================== */

p.person-name{
  --p-size:.95rem;
  --p-color:#6393cd;             /* the older `color:#6393cd !important` above is
                                    UNLAYERED, so @layer base beat it and the name
                                    was rendering grey. Trap 13: anything that must
                                    survive goes through --p-*. I set --p-margin
                                    here and forgot --p-color; the check caught it. */
  --p-margin:0 0 .15em;          /* the pair reads as one unit */
  -webkit-text-fill-color:#6393cd;
}

p.person-role{
  --p-size:.95rem;
  --p-color:#6393cd;
  --p-margin:0 0 1.1em;          /* the space before the email address */
  font-family:var(--sans);
  font-weight:700;
  -webkit-text-fill-color:#6393cd;
}


/* ==========================================================================
   25. The Split kit block — sections become ONE block, edited in the sidebar
   2026-08-23. Simon, correctly: the pages were built as loose Kadence columns
   and core paragraphs, so content is typed into the canvas and a client can
   drag a layout apart. HCML and ideate put the content in the right-hand
   sidebar and the section holds together. This build did not.

   The cause was a specification error, not just haste: pattern-library.md named
   "Baseplate Split" for these sections without checking the block could hold
   the content. It could not — no second heading, no list — so the build fell
   back to raw blocks to get the copy in. Split now carries the whole shape:

     kicker · heading · body · second heading · tick list · closing copy
     · image · image-on-the-left

   One block, every field in the sidebar, nothing loose in the canvas. The
   styling below reproduces what the raw blocks used to render, so converting a
   section changes the markup and the editing experience but not the page.
   ========================================================================== */

.split{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:56px;
  align-items:start;
}

.split--reverse .split__copy{ order:2; }
.split--reverse .split__media{ order:1; }

.split__media img,
.split__media video{
  display:block;
  width:100%;
  height:auto;
}

/* NOTE: real `color` and `font-size`, not only the --p-* custom properties.
   Those properties are read by the @layer neutraliser (section 12), which only
   matches paragraphs that are DIRECT children of `.kt-inside-inner-col`. The
   copy inside this block sits in `.split__copy`, so the neutraliser never sees
   it and a --p-color alone did nothing — the closing paragraph stayed on
   HCML's grey. Both are set: the property for where the layer applies, the
   declaration for everywhere else. */

.split__kicker{
  --p-color:var(--accent);
  --p-size:.95rem;
  --p-margin:0 0 1.1em;
  color:var(--accent);
  font-family:var(--sans);
  font-size:.95rem;
  font-weight:700;
  margin:0 0 1.1em;
}

.split .proj-section__h{
  font-family:var(--serif);
  color:var(--ink);
  font-size:clamp(1.5rem, 2.4vw, 2rem);
  font-weight:400;
  line-height:1.2;
  margin:0 0 .6em;
}

/* Lead-in rows inside the Split block. `.list-lead` supplies the accent colour
   and weight (with !important, so it holds), but not size or rhythm — and the
   @layer neutraliser never reaches inside `.split__copy`, so both are stated
   here. Added 2026-08-23 when the service bodies became flexible-content rows. */

.split .split__lead{
  --p-size:.95rem;
  --p-margin:1.6em 0 .8em;
  font-size:.95rem;
  line-height:1.7;
  margin:1.6em 0 .8em;
}

/* An image dropped inside the copy column, e.g. Cashflow Planning's second
   image, which the old fixed-field Split could not hold at all. */

.split .split__figure{
  margin:1.6em 0 0;
}

.split .split__figure img,
.split .split__figure video{
  display:block;
  width:100%;
  height:auto;
}

.split .split__h2{
  font-size:clamp(1.2rem, 1.8vw, 1.5rem);
  margin:1.4em 0 .7em;
}

.split .proj-section__p{
  --p-color:var(--grey);
  --p-size:.95rem;
  --p-margin:0 0 1.1em;
  color:var(--grey);
  font-size:.95rem;
  line-height:1.7;
  margin:0 0 1.1em;
}

/* The tick list, drawn the same way as the icon list it replaces. */
.split__ticks{
  list-style:none;
  margin:0 0 1.3em;
  padding:0;
}

.split__ticks li{
  position:relative;
  padding-left:30px;
  margin:0 0 .6em;
  color:var(--grey);
  font-size:.95rem;
  line-height:1.6;
}

.split__ticks li::before{
  content:"";
  position:absolute;
  left:0;
  top:.42em;
  width:15px;
  height:15px;
  background-color:var(--accent);
  -webkit-mask:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20512%20512%27%3E%3Cpath%20d%3D%27M173.9%20439.4l-166.4-166.4c-10-10-10-26.2%200-36.2l36.2-36.2c10-10%2026.2-10%2036.2%200L192%20312.7%20432.1%2072.6c10-10%2026.2-10%2036.2%200l36.2%2036.2c10%2010%2010%2026.2%200%2036.2l-294.4%20294.4c-10%2010-26.2%2010-36.2%200z%27%2F%3E%3C%2Fsvg%3E") no-repeat center / contain;
  mask:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20512%20512%27%3E%3Cpath%20d%3D%27M173.9%20439.4l-166.4-166.4c-10-10-10-26.2%200-36.2l36.2-36.2c10-10%2026.2-10%2036.2%200L192%20312.7%20432.1%2072.6c10-10%2026.2-10%2036.2%200l36.2%2036.2c10%2010%2010%2026.2%200%2036.2l-294.4%20294.4c-10%2010-26.2%2010-36.2%200z%27%2F%3E%3C%2Fsvg%3E") no-repeat center / contain;
}

@media (max-width:900px){
  .split{ grid-template-columns:1fr; gap:32px; }
  .split--reverse .split__copy,
  .split--reverse .split__media{ order:0; }
}


/* ==========================================================================
   26. The Testimonial kit block — photograph, editable shading, one block
   2026-08-23. The testimonial was a Kadence Section carrying a background
   image, with the quote and the attribution as two loose paragraphs and the
   shading hard-coded in this stylesheet. So the quote and the name were
   separate blocks in the editor, and the shading could only be changed here.

   It is now one `acf/testimonial` with fields: Quote, Name, Role / company,
   Background photograph, Shading colour, Shading strength (0-100%).

   The shading is a block field for a real reason recorded in the ledger: the
   preview's alpha values did NOT transfer between photographs — a wash that
   looked right on a dark image was nearly invisible on Cambourne's bright
   bamboo shot. Whoever picks the picture has to be able to tune the wash to it,
   without a developer.

   The Section no longer pads (section 19), because the photograph has to reach
   the screen edge; the block holds the measure on its own inner element.
   ========================================================================== */

/* The Section's inner column is a flex column that aligns its children to the
   end (an older rule for the right-aligned quote). A flex item does not stretch
   on the main axis, so the block sized to its own content — 880px of quote plus
   56px of padding = 936 — and sat flush right instead of filling the band.
   Both the ACF wrapper and the block itself have to be told to fill. */
.wp-block-testimonial,
.align.wp-block-testimonial{
  width:100%;
  align-self:stretch;
}

/* Belt and braces for the editor: whatever wrapper the block editor puts between
   the Section's inner column and the block markup, it must not shrink-wrap. ACF's
   own CSS sets only `min-height` on `.acf-block-preview`, so the capping was never
   ACF's doing — it was the flex rule above. These are named anyway because the
   editor's wrapper markup is version-dependent and this file cannot see it. */
.editor-styles-wrapper .sec-quote .acf-block-preview,
.editor-styles-wrapper .sec-quote .wp-block-acf-testimonial,
.editor-styles-wrapper .sec-quote .wp-block-testimonial{
  width:100%;
  max-width:none;
  align-self:stretch;
  margin-left:0;
  margin-right:0;
}

.testimonial--photo{
  position:relative;
  display:flex;
  align-items:center;
  width:100%;
  min-height:500px;          /* live band height, measured */
  overflow:hidden;
}

.testimonial__media{
  position:absolute;
  inset:0;
  background-size:cover;
  background-position:center 30%;
  background-repeat:no-repeat;
}

.testimonial__scrim{
  position:absolute;
  inset:0;
  background:var(--t-overlay, #0c2340);
  opacity:var(--t-overlay-opacity, .58);
}

.testimonial__inner{
  position:relative;
  z-index:1;
  width:100%;
  max-width:1130px;
  margin:0 auto;
  padding:64px 28px;
  text-align:right;
}

.testimonial--photo blockquote{
  margin:0 0 26px;
  padding:0;
  border:0;
  font-family:var(--serif);
  font-size:22px;
  font-weight:300;
  font-style:normal;
  line-height:1.25;
  color:#ffffff;
  -webkit-text-fill-color:#ffffff;
  max-width:880px;
  margin-left:auto;
  text-shadow:0 1px 12px rgba(5,14,28,.55);
}

/* The field instructions promise the marks are added for you, so add them. */
.testimonial--photo blockquote::before{ content:"\201C"; }
.testimonial--photo blockquote::after{ content:"\201D"; }

.testimonial--photo .testimonial__attr{
  font-family:var(--sans);
  font-size:.78rem;
  font-weight:700;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:#e8eef7;
  -webkit-text-fill-color:#e8eef7;
}

.testimonial--photo .testimonial__attr strong{
  font-weight:700;
  color:inherit;
}

.testimonial--photo .testimonial__attr strong + *::before{ content:", "; }

@media (max-width:900px){
  .testimonial__inner{ padding:44px 28px; text-align:left; }
  .testimonial--photo blockquote{ margin-left:0; }
}
