/*
Theme Name: Amy Hutson Counselling Child
Theme URI: https://amyhutsoncounselling.co.uk/
Description: Child theme for Divi 5, built for the 2026 site rebuild.
Author: WebsiteAbility
Author URI: https://websiteability.com/
Template: Divi
Version: 1.54.0
Requires at least: 6.0
Requires PHP: 7.4
License: GNU General Public License v2
License URI: http://www.gnu.org/licenses/gpl-2.0.html
*/

/* Child styles go below this line.
   Deliberately empty at creation. The Divi 4 site's customisations lived in
   Theme Options Custom CSS and are being retired rather than ported, per the
   header and footer audit of 6 September 2026.

   Divi 5 enqueues this file itself as divi-style-child, after divi-dynamic
   and before et-divi-customizer. See functions.php for the detail. */

/* ============================================================================
   Watercolour design system treatments that Divi 5's option UI cannot express:
   masks, washes, grain, rotation, blend modes, keyframes and nth-child rules.
   Extracted from `site_system.py` (07 - Build Source) and checked against the
   Divi 5 design system spec, section 6, and the Divi 5 build notes, sections
   3 and 5. Fifteen items, numbered to match the spec's own table.

   Colours that are one of Amy's palette tokens are written as the matching
   Divi Design Variable custom property rather than as a hex literal, so a
   palette change carries through here too. Sizes and spacing stay literal:
   Divi 5 Number variables do not emit CSS custom properties.
   ============================================================================ */

/* 1. Paper grain overlay. An SVG feTurbulence filter as a fixed, near-invisible
   background, sitting behind everything at a very low opacity so contrast is
   untouched. Divi's Design tab has no field for an SVG filter background. */
body::before{content:"";position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.055;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");}
/* The grain sits at z-index 0, so main and footer need to be lifted above it
   or the whole page renders behind the texture instead of on top of it. */
main,footer{position:relative;z-index:1;}
/* Superseded by item 12's `position:fixed`, declared later in this file and
   winning the cascade. Left in for source fidelity; removing it changes nothing
   visible. */
.progress{position:relative;}
/* Lifted above main (z-index 1) with its own stacking context, or the mobile
   menu panel drops behind the page content once main is promoted. */
header{position:sticky;z-index:40;}

/* 2. Washed section edges. A mask on a pseudo-element, tinted with the band's
   own background via `background:inherit`, so one band meets the next with a
   soft irregular line instead of a hard rectangle edge. */
.band-sage,.band-rose,.band-card,.band-deep{position:relative;}
.band-sage::before,.band-rose::before,.band-card::before,.band-deep::before{
  content:"";position:absolute;left:0;right:0;top:-13px;height:14px;
  background:inherit;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 14' preserveAspectRatio='none'%3E%3Cpath d='M0 14 C60 3 90 12 150 9 C220 5 260 13 330 10 C400 7 440 2 510 8 C580 13 620 4 700 7 C780 10 820 2 900 6 C980 10 1030 13 1100 8 C1150 4 1180 11 1200 9 L1200 14 Z' fill='%23000'/%3E%3C/svg%3E") bottom/100% 100% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 14' preserveAspectRatio='none'%3E%3Cpath d='M0 14 C60 3 90 12 150 9 C220 5 260 13 330 10 C400 7 440 2 510 8 C580 13 620 4 700 7 C780 10 820 2 900 6 C980 10 1030 13 1100 8 C1150 4 1180 11 1200 9 L1200 14 Z' fill='%23000'/%3E%3C/svg%3E") bottom/100% 100% no-repeat;}

/* 3. Painted heading underline. A brush-shaped SVG mask on h2::after rather
   than a straight rule.

   Fixed here: the source's deep-sage override selector was missing a comma
   and the `.band-deep` prefix on three of its four selectors, so as written
   it would have turned every h2 underline on the whole site white at 50%
   opacity, not only the ones inside a deep sage band. On the linen and cream
   bands that would have made the underline almost invisible. Corrected to
   the evident intent, a deep-sage-only override; see the build report for
   the exact source line. */
.sec-head h2,.narrow > h2,.panel > h2,.prose h2{position:relative;padding-bottom:.5rem;}
.sec-head h2::after,.narrow > h2::after,.panel > h2::after,.prose h2::after{content:"";position:absolute;left:0;bottom:0;width:clamp(72px,19%,138px);height:11px;
  background:var(--gcid-ahc-sage-mid);opacity:.72;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 11' preserveAspectRatio='none'%3E%3Cdefs%3E%3ClinearGradient id='b' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='%23000' stop-opacity='.3'/%3E%3Cstop offset='.16' stop-color='%23000' stop-opacity='1'/%3E%3Cstop offset='.6' stop-color='%23000' stop-opacity='.94'/%3E%3Cstop offset='.87' stop-color='%23000' stop-opacity='.5'/%3E%3Cstop offset='1' stop-color='%23000' stop-opacity='.22'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M2 5.9 C8 4.9 14 4.4 20 4.2 C28 3.9 34 3.4 40 3.2 C48 3 54 3 60 3.1 C68 3.3 74 3.6 80 3.9 C88 4.3 94 4.6 100 4.9 C104 5.1 107 5.4 110 5.7 L110 7.1 C106 7.3 103 7.6 100 7.9 C93 8.1 87 8.2 80 8.3 C73 8.4 66 8.45 60 8.5 C53 8.35 46 8.2 40 8 C33 7.8 26 7.7 20 7.6 C13 7.4 7 7.1 2 6.9 Z M113.6 5.9 C115.5 5.7 117.4 5.9 119 5.8 L119 6.8 C117.2 7 115.3 6.9 113.6 7.1 Z' fill='url(%23b)'/%3E%3C/svg%3E") left/100% 100% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 11' preserveAspectRatio='none'%3E%3Cdefs%3E%3ClinearGradient id='b' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='%23000' stop-opacity='.3'/%3E%3Cstop offset='.16' stop-color='%23000' stop-opacity='1'/%3E%3Cstop offset='.6' stop-color='%23000' stop-opacity='.94'/%3E%3Cstop offset='.87' stop-color='%23000' stop-opacity='.5'/%3E%3Cstop offset='1' stop-color='%23000' stop-opacity='.22'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M2 5.9 C8 4.9 14 4.4 20 4.2 C28 3.9 34 3.4 40 3.2 C48 3 54 3 60 3.1 C68 3.3 74 3.6 80 3.9 C88 4.3 94 4.6 100 4.9 C104 5.1 107 5.4 110 5.7 L110 7.1 C106 7.3 103 7.6 100 7.9 C93 8.1 87 8.2 80 8.3 C73 8.4 66 8.45 60 8.5 C53 8.35 46 8.2 40 8 C33 7.8 26 7.7 20 7.6 C13 7.4 7 7.1 2 6.9 Z M113.6 5.9 C115.5 5.7 117.4 5.9 119 5.8 L119 6.8 C117.2 7 115.3 6.9 113.6 7.1 Z' fill='url(%23b)'/%3E%3C/svg%3E") left/100% 100% no-repeat;}
.band-deep .sec-head h2::after,.band-deep .narrow > h2::after,.band-deep .panel > h2::after,.band-deep .prose h2::after{background:var(--gcid-ahc-white);opacity:.5;}

/* 4. Deckle paper swatch. An SVG mask tears the panel edge, and `rotate` (not
   `transform`) tilts it slightly, so Divi's Module Animation can still set
   `transform:none` on arrival without straightening the swatch. A mask clips
   a box shadow, so the hover state removes the default shadow rather than
   adding one: movement is the only hover cue here, never a shadow. */
.set-swatch > *,.swatch{background:var(--gcid-ahc-cream);padding:1.7rem 1.6rem;border:0;border-radius:0;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M1 2 C24 0.4 50 2.2 74 1 C86 0.4 96 1.8 99 1.2 L99.2 98.6 C76 99.8 50 98 26 99.2 C14 99.8 4 98.4 1 99 Z' fill='%23000'/%3E%3C/svg%3E") center/100% 100% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M1 2 C24 0.4 50 2.2 74 1 C86 0.4 96 1.8 99 1.2 L99.2 98.6 C76 99.8 50 98 26 99.2 C14 99.8 4 98.4 1 99 Z' fill='%23000'/%3E%3C/svg%3E") center/100% 100% no-repeat;}
.set-swatch > *:nth-child(2n){rotate:-.5deg;}
.set-swatch > *:nth-child(3n){rotate:.6deg;}
.set-swatch > *:hover,.swatch:hover{box-shadow:none;}
/* On a cream band the swatch would vanish into it, so it takes the linen tone instead. */
.band-card .set-swatch > *,.band-card .swatch{background:var(--gcid-ahc-linen);}

/* 5. Painted rule under swatch headings. Fixed at 58px rather than full
   width: stretched across a whole panel the brush mask flattens out and
   reads as a plain horizontal rule under a two-word heading. */
.set-swatch h3,.swatch h3{position:relative;padding-bottom:.75rem;margin-bottom:.8rem;}
.set-swatch h3::after,.swatch h3::after{content:"";position:absolute;left:0;bottom:0;width:58px;height:7px;
  background:var(--gcid-ahc-sage-mid);opacity:.7;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 8' preserveAspectRatio='none'%3E%3Cpath d='M1 5.4 C20 1.8 40 6.8 60 3.8 C80 0.9 100 6.2 119 3.2 L119 7.4 C100 8 80 5.6 60 7 C40 8.4 20 7.2 1 7.8 Z' fill='%23000'/%3E%3C/svg%3E") left/100% 100% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 8' preserveAspectRatio='none'%3E%3Cpath d='M1 5.4 C20 1.8 40 6.8 60 3.8 C80 0.9 100 6.2 119 3.2 L119 7.4 C100 8 80 5.6 60 7 C40 8.4 20 7.2 1 7.8 Z' fill='%23000'/%3E%3C/svg%3E") left/100% 100% no-repeat;}

/* 6. Deckle image edge. The same torn-paper mask idea, applied to photographs
   and illustrations rather than a panel, so images read as paper torn from a
   pad instead of a hard-edged rectangle. */
/* Hero watercolours added to this list 8 September 2026, at Alex's request.
   The mock-ups deliberately leave them unmasked: the paintings already have
   open, uneven washes at their edges, so the deckle was reserved for the
   photograph, which is a hard-edged rectangle and needs it. Masking them too
   is a deliberate change to the design, not a correction of it, and it works
   because the 4:3 crop in part twenty-four gives them a hard edge they did not
   have before. Scoped to the hero so post thumbnails and card crops are
   untouched. */
.portrait img,.shotfig img,.post .thumb img,.prose img,.wrap > img,
#et-boc .hero-sec .drift img,
#et-boc .ahc-404-fig img{
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M0.8 1.2 C26 0.2 52 1.8 76 0.6 C88 0 97 1.4 99.2 0.9 L99.4 99 C74 99.8 48 98.4 24 99.4 C13 99.9 4 98.6 0.6 99.2 Z' fill='%23000'/%3E%3C/svg%3E") center/100% 100% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M0.8 1.2 C26 0.2 52 1.8 76 0.6 C88 0 97 1.4 99.2 0.9 L99.4 99 C74 99.8 48 98.4 24 99.4 C13 99.9 4 98.6 0.6 99.2 Z' fill='%23000'/%3E%3C/svg%3E") center/100% 100% no-repeat;}

/* 7. Washed left edge on capsules and pull-outs. A mask on a pseudo-element
   replaces a straight coloured border-left, so the edge has an uneven brush
   profile rather than a ruled line. The Text preset for each of these still
   supplies its own padding, background and radius; only the edge is here. */
.capsule,.tldr,.boundary{position:relative;border-left:0;}
.capsule::before,.tldr::before,.boundary::before{content:"";position:absolute;left:0;top:0;bottom:0;
  width:6px;background:var(--gcid-secondary-color);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 100' preserveAspectRatio='none'%3E%3Cpath d='M1.6 0 C4.6 12 1.2 26 3.4 40 C5.4 54 1.4 66 3.2 80 C4.6 90 2.2 95 3 100 L6 100 L6 0 Z' fill='%23000'/%3E%3C/svg%3E") left/100% 100% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 100' preserveAspectRatio='none'%3E%3Cpath d='M1.6 0 C4.6 12 1.2 26 3.4 40 C5.4 54 1.4 66 3.2 80 C4.6 90 2.2 95 3 100 L6 100 L6 0 Z' fill='%23000'/%3E%3C/svg%3E") left/100% 100% no-repeat;}
.tldr.rose::before{background:var(--gcid-ahc-rose-deep);}
.boundary::before{background:var(--gcid-ahc-rose-deep);}

/* 8. Portrait washes. Four overlapping radial gradients with a blur filter,
   sat behind the photo with no outline at all: a wash only reads as a wash
   when it has no hard edge. `isolation:isolate` and the explicit z-index keep
   the gradients under the image rather than over it. The eight rgba() values
   below are gradient stops, not colour fields, so per spec section 4.1.1 they
   stay literal rather than becoming Design Variable references. */
.portrait{position:relative;isolation:isolate;}
.portrait img{position:relative;z-index:1;}
.portrait::after{content:"";position:absolute;z-index:0;
  inset:38% -9% -9% 42%;
  background:
    radial-gradient(64% 62% at 52% 56%, rgba(165,189,167,.95), rgba(165,189,167,.5) 54%, rgba(165,189,167,0) 86%),
    radial-gradient(44% 48% at 82% 26%, rgba(165,189,167,.7), rgba(165,189,167,0) 82%);
  filter:blur(5px);}
.portrait::before{content:"";position:absolute;z-index:0;
  inset:-9% 66% 70% -9%;
  background:
    radial-gradient(66% 62% at 56% 56%, rgba(213,154,154,.6), rgba(213,154,154,.3) 56%, rgba(213,154,154,0) 86%),
    radial-gradient(44% 46% at 30% 26%, rgba(213,154,154,.42), rgba(213,154,154,0) 84%);
  filter:blur(6px);}

/* 9. Painted link underline. An animated `background-size` on a two-colour
   gradient, so the underline washes upward into a soft highlight on hover
   rather than a plain colour swap. The hover wash uses the Link Wash Hover
   relative colour from spec section 4.1.1, created in Divi on 7 September 2026
   as gcid-ahc-link-wash-hover: Rose Deep at 28 per cent. */
.prose a,p a,li a{text-decoration:none;background-repeat:no-repeat;
  background-image:linear-gradient(var(--gcid-heading-color),var(--gcid-heading-color));
  background-size:100% 1px;background-position:0 95%;padding-bottom:1px;
  transition:background-size .22s ease,background-color .18s ease;}
.prose a:hover,p a:hover,li a:hover{
  background-image:linear-gradient(var(--gcid-ahc-link-wash-hover),var(--gcid-ahc-link-wash-hover));
  background-size:100% 42%;background-position:0 88%;color:var(--gcid-ahc-rose-deep);}
.band-sage p a,.band-rose p a,.band-sage li a,.band-rose li a{
  background-image:linear-gradient(var(--gcid-body-color),var(--gcid-body-color));}

/* 10. Organic bullets. An irregular border-radius with a fixed rotation gives
   each bullet a hand-painted mark rather than a perfect circle. This uses
   `transform`, not `rotate`: unlike the paper swatches, this mark is never a
   target of Divi's Module Animation, so there is no `transform:none` on
   arrival to guard against. */
ul.plain li::before,.prose ul li::before{border-radius:56% 44% 60% 40% / 48% 62% 38% 52%;
  width:8px;height:7px;transform:rotate(-8deg);}

/* 11. Button wash on hover. A desaturated turbulence filter fades in over the
   button on hover via `mix-blend-mode:overlay`, standing in for a flat
   background colour change. Carries no palette colour of its own. */
.btn{position:relative;overflow:hidden;}
.btn::after{content:"";position:absolute;inset:0;opacity:0;transition:opacity .2s ease;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='60'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.04 0.09' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='120' height='60' filter='url(%23w)' opacity='0.5'/%3E%3C/svg%3E");
  mix-blend-mode:overlay;pointer-events:none;}
.btn:hover::after{opacity:.5;}

/* 12. Reading progress bar. A masked fixed element with uneven ends, driven
   by the Code module's scroll script (build notes section 3), which only
   ever sets `width`; the shape, colour and position all live here. */
.progress{position:fixed;top:0;left:0;height:5px;width:0;background:var(--gcid-primary-color);z-index:60;
  transition:width .1s linear;opacity:.85;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 5' preserveAspectRatio='none'%3E%3Cpath d='M0 1.6 C30 0.4 60 2.6 92 1.4 C126 0.2 160 2.4 200 1.2 L200 4 C164 4.8 128 3.2 96 4.2 C62 5 30 3.6 0 4.4 Z' fill='%23000'/%3E%3C/svg%3E") left/100% 100% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 5' preserveAspectRatio='none'%3E%3Cpath d='M0 1.6 C30 0.4 60 2.6 92 1.4 C126 0.2 160 2.4 200 1.2 L200 4 C164 4.8 128 3.2 96 4.2 C62 5 30 3.6 0 4.4 Z' fill='%23000'/%3E%3C/svg%3E") left/100% 100% no-repeat;}
@media (prefers-reduced-motion:reduce){.progress{transition:none;}}

/* 13. Marquee. A CSS keyframe animation slides a doubled track left by 50%,
   which is what makes the loop seamless. The family is named directly because
   Divi Font variables resolve into module CSS and emit no custom property.
   "Fraunces Self-Hosted" is the uploaded variable font registered in Divi on
   7 September 2026; Divi refuses a custom font sharing a name with one of its
   built-in Google fonts, which is why the name carries the qualifier. */
.marquee{overflow:hidden;border-top:1px solid var(--gcid-ahc-border-hairline);
  border-bottom:1px solid var(--gcid-ahc-border-hairline);padding:1.5rem 0;background:var(--gcid-ahc-cream);}
.marquee .track{display:flex;gap:3rem;align-items:center;white-space:nowrap;
  font-family:'Fraunces Self-Hosted','Fraunces',Georgia,serif;font-size:clamp(1.2rem,2.4vw,1.75rem);color:var(--gcid-heading-color);
  animation:slide 34s linear infinite;}
.marquee .dot{width:7px;height:7px;border-radius:50%;background:var(--gcid-ahc-rose-deep);flex:none;}
@keyframes slide{from{transform:translateX(0);}to{transform:translateX(-50%);}}
@media (prefers-reduced-motion:reduce){.marquee .track{animation:none;}}

/* 14. Zebra striping. An nth-child(odd) rule tints alternating rows, which
   Divi's Design tab cannot apply across a repeated set of separate modules. */
.set-zebra > *:nth-child(odd){background:var(--gcid-ahc-cream);border-radius:6px;}
.band-card .set-zebra > *:nth-child(odd){background:var(--gcid-ahc-linen);}

/* 15. Hairline ruled list. Every item carries a top hairline, and nth-child
   suppresses it for the first row (the first two items, side by side), which
   keeps every item on the same shared preset rather than styling the first
   row's modules differently by hand. */
.set-ruled > *{border-top:1px solid var(--gcid-ahc-border-hairline-strong);}
.set-ruled > *:nth-child(1),.set-ruled > *:nth-child(2){border-top:0;}

/* Responsive adjustments needed by two of the treatments above. Both come
   from the same source media query; only the parts touching items 8 and 15
   are carried over; the rest of that query is unrelated page layout that
   Divi's own responsive stacking already handles. */
@media (max-width:900px){
  /* Item 8. The wash bleeds 9% past the print edge, which at 390px pushed
     12px past the viewport and gave every portrait page a horizontal scroll.
     Below this breakpoint the bleed becomes a fixed 14px and the portrait
     takes a 16px margin, so the wash always has room inside the page. */
  .portrait{max-width:420px;margin-left:16px;margin-right:16px;}
  .portrait::after{inset:38% -14px -14px 42%;}
  .portrait::before{inset:-14px 66% 70% -14px;}

  /* Item 15. Below this breakpoint the row stacks to one column, so the
     second item is no longer sharing the top row with the first and needs
     its hairline restored. */
  .set-ruled > *:nth-child(2){border-top:1px solid var(--gcid-ahc-border-hairline-strong);}
}

/* ============================================================================
   Part two: component and layout CSS for classes that live inside Divi 5 Text
   module content, which the Divi Design tab cannot reach. Extracted from the
   CSS, WATERCOLOUR_CSS and MOTION_CSS constants in site_system.py. Anything
   already covered by the watercolour block above this fragment (paper grain,
   washed edges, painted underlines, masks, portrait washes, painted links,
   organic bullets, button wash, progress bar, marquee, zebra striping, ruled
   hairlines) is deliberately not repeated here.

   Colours matching Amy's palette are written as the Divi Design Variable, per
   the build spec's colour table. Sizes, spacing and radii stay literal, since
   Divi Number variables emit no custom property. Font stacks are written out
   in full for the same reason.
   ============================================================================ */

/* Layout tokens. Not colours, so not Design Variables; .wrap, .narrow and the
   mobile nav panel below all read these. */
:root{--wrap:1180px;--narrow:760px;--gut:clamp(20px,5vw,56px);}

/* ---------------------------------------------------------------- wrappers */
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--gut);}
.narrow{max-width:var(--narrow);margin:0 auto;padding:0 var(--gut);}

/* ---------------------------------------------------------------- text bits */
.eyebrow{font-family:'Inter Self-Hosted',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:.775rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--gcid-ahc-rose-deep);margin-bottom:1rem;}
.lede{font-size:1.1rem;}
.small{font-size:.94rem;color:var(--gcid-ahc-ink-muted);}

/* Paragraph spacing. Not base p typography (family/size/colour/line-height),
   which the body preset owns; this is measure and vertical rhythm only. */
p{max-width:64ch;margin-bottom:1.12rem;}
p:last-child{margin-bottom:0;}
h1 + p,h2 + p,h3 + p{margin-top:1rem;}
.card p:last-child,.step p:last-child,.post p:last-child{margin-bottom:0;}

/* ---------------------------------------------------------------- buttons */
/* Colour, background, padding and radius are the preset's job. This is the
   flex layout, the 44px+ touch target and the two interaction states. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  min-height:52px;font-family:'Inter Self-Hosted',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:1rem;font-weight:600;text-decoration:none;border:0;cursor:pointer;
  transition:background-color .12s,transform .12s;}
.btn:hover{transform:translateY(-1px);}
.btn:active{transform:translateY(0) scale(.985);}

/* ---------------------------------------------------------------- header */
header{background:var(--gcid-ahc-cream);border-bottom:1px solid var(--gcid-ahc-border-hairline);
  position:sticky;top:0;z-index:40;}
/* position:sticky and z-index:40 on header are already set in the watercolour
   block above; top:0 was not, so header is restated here for that property only. */
.hd{display:flex;align-items:center;gap:1.5rem;min-height:84px;}
.hd .logo{display:flex;align-items:center;text-decoration:none;}
.hd .logo svg{height:46px;width:auto;}
nav.main{margin-left:auto;display:flex;align-items:center;gap:1.5rem;}
nav.main a:not(.btn){font-size:.95rem;color:var(--gcid-body-color);text-decoration:none;padding:.35rem 0;}
nav.main a:not(.btn):hover{color:var(--gcid-heading-color);}
nav.main a:not(.btn)[aria-current]{color:var(--gcid-heading-color);}
nav.main a{white-space:nowrap;}
nav.main .btn{min-height:44px;font-size:.92rem;margin-left:.3rem;}
/* Seven nav items plus the booking button run out of room between the mobile
   breakpoint and about 1150px; tighten gaps rather than drop an item. */
@media (min-width:901px) and (max-width:1150px){
  nav.main{gap:1.05rem;}
  nav.main a:not(.btn){font-size:.9rem;}
  nav.main .btn{font-size:.88rem;}
}

/* Mobile menu. Hidden above the breakpoint, where the full nav is on show.
   The summary element is a bespoke hamburger toggle, not a Divi button, so
   its colour and box-shadow are not preset territory and stay here in full. */
.mobnav{display:none;}
.mobnav > summary{list-style:none;display:inline-flex;align-items:center;gap:.55rem;
  min-height:44px;padding:.55rem .95rem;border-radius:6px;cursor:pointer;
  font-family:'Inter Self-Hosted',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:.95rem;font-weight:600;color:var(--gcid-heading-color);
  box-shadow:inset 0 0 0 1.6px var(--gcid-heading-color);}
.mobnav > summary::-webkit-details-marker{display:none;}
.mobnav > summary .bars{width:18px;height:2px;background:currentColor;position:relative;flex:none;}
.mobnav > summary .bars::before,.mobnav > summary .bars::after{content:"";position:absolute;
  left:0;width:18px;height:2px;background:currentColor;}
.mobnav > summary .bars::before{top:-6px;} .mobnav > summary .bars::after{top:6px;}
.mobnav[open] > summary .bars{background:transparent;}
.mobnav[open] > summary .bars::before{top:0;transform:rotate(45deg);}
.mobnav[open] > summary .bars::after{top:0;transform:rotate(-45deg);}
.mobnav .panel-nav{position:absolute;left:0;right:0;top:100%;background:var(--gcid-ahc-cream);
  border-bottom:1px solid var(--gcid-ahc-border-hairline);box-shadow:0 12px 26px var(--gcid-ahc-drop-shadow);
  padding:.6rem var(--gut) 1.3rem;display:flex;flex-direction:column;z-index:45;}
.mobnav .panel-nav a:not(.btn){display:block;padding:.85rem 0;min-height:44px;font-size:1.05rem;
  color:var(--gcid-body-color);text-decoration:none;border-bottom:1px solid var(--gcid-ahc-border-hairline-faint);}
.mobnav .panel-nav a:not(.btn)[aria-current]{color:var(--gcid-heading-color);font-weight:600;}
.mobnav .panel-nav a:not(.btn):last-of-type{border-bottom:0;}
/* :not(.btn) matters: without it this rule beats .btn on specificity and
   strips the booking button's centring. Colour is left to the preset. */
.mobnav .panel-nav .btn{display:flex;justify-content:center;align-items:center;
  margin-top:1.2rem;text-decoration:none;}

/* Sticky header shrink on scroll. Divi 5: Sticky Position with sticky-state
   styles could do this instead; kept here as the source pattern. */
header{transition:box-shadow .25s ease,background-color .25s ease;}
header .hd{transition:min-height .25s ease;}
header.shrunk{box-shadow:0 2px 16px var(--gcid-ahc-drop-shadow);}
header.shrunk .hd{min-height:66px;}
header.shrunk .logo svg{height:38px;transition:height .25s ease;}
header .logo svg{transition:height .25s ease;}

/* Nav underline draw on hover and current-page state, replacing a static
   border-bottom with an animated one. */
nav.main a:not(.btn){position:relative;border-bottom:0;}
nav.main a:not(.btn)::after{content:"";position:absolute;left:0;right:100%;bottom:0;height:2px;
  background:var(--gcid-ahc-sage-mid);transition:right .26s cubic-bezier(.22,.61,.36,1);}
nav.main a:not(.btn):hover::after,nav.main a[aria-current]::after{right:0;background:var(--gcid-primary-color);}

/* ---------------------------------------------------------------- definition pairs */
/* Requested as "definition lists"; the source builds this with a div, h3 and
   p rather than dl/dt/dd, so that is what is reproduced here. */
.defs{display:grid;grid-template-columns:1fr 1fr;gap:2rem 3rem;}
.defs h3{font-family:'Inter Self-Hosted',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:.95rem;font-weight:600;color:var(--gcid-heading-color);letter-spacing:.02em;margin-bottom:.5rem;}
.defs p{font-size:1rem;}

/* ---------------------------------------------------------------- panel */
.panel{background:var(--gcid-ahc-cream);border-radius:12px;padding:clamp(1.9rem,3.6vw,3.1rem);}
.panel a:not(.btn){color:var(--gcid-heading-color);}
.panel a:not(.btn):hover{color:var(--gcid-ahc-rose-deep);}
.panel .capsule{background:var(--gcid-ahc-linen);}
.sec-head{margin-bottom:2.1rem;max-width:64ch;}
.sec-head p{margin-top:.9rem;}
/* .panel h1..h4{color:var(--terra-d)} and .panel .eyebrow{color:var(--rose-d)}
   from the source are dropped: both values equal what the heading-colour
   Design Variable and the base .eyebrow rule above already produce, so they
   were a no-op even in the mock-up. */

/* ---------------------------------------------------------------- capsule, tldr, boundary */
/* The watercolour block above already replaces the straight border-left with
   a masked wash and sets border-left:0. Only the box itself is added here. */
.capsule{background:var(--gcid-ahc-cream);border-radius:0 8px 8px 0;padding:1.3rem 1.5rem;margin:1.1rem 0 1.6rem;}
.capsule p{margin:0;font-size:1.04rem;}
.band-card .capsule{background:var(--gcid-ahc-linen);}
.tldr{background:var(--gcid-ahc-cream);border-radius:10px;padding:1.7rem 1.8rem;margin:2rem 0;}
.tldr h2{font-size:1.05rem;font-family:'Inter Self-Hosted',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--gcid-heading-color);margin:0 0 .9rem;}
.boundary{background:var(--gcid-ahc-linen);border-radius:0 8px 8px 0;padding:1.3rem 1.5rem;margin:1.6rem 0;}
.boundary p{margin:0;font-size:1rem;}
.band-card .boundary{background:var(--gcid-ahc-cream);}
/* .tldr.rose{border-left-color:...} from the source is dropped: border-left
   is 0 (the mask owns the edge colour via .tldr.rose::before), so a border
   colour on a zero-width border painted nothing. */

/* ---------------------------------------------------------------- item-set treatments */
/* set-swatch's own box (mask, background, rotation) and set-zebra's and
   set-ruled's alternating/hairline colouring are already in the watercolour
   block above. This is the grid layout and the neutral resets underneath. */
.set-steps:not(.et_pb_row){display:grid;grid-template-columns:repeat(3,1fr);gap:2.4rem 3rem;}
.set-steps .step{background:transparent;border:0;border-radius:0;padding:0;}
.set-steps .step:hover{transform:none;box-shadow:none;}
.set-steps .step .n{display:block;width:auto;height:auto;background:none;border-radius:0;
  color:var(--gcid-secondary-color);font-family:'Fraunces Self-Hosted',Georgia,'Times New Roman',serif;
  font-size:2.6rem;line-height:1;margin-bottom:.4rem;}

.set-zebra > *{display:grid;grid-template-columns:1fr 2fr;gap:2.4rem;align-items:baseline;
  padding:1.5rem clamp(1rem,3vw,2.2rem);background:transparent;border:0;border-radius:0;}
.set-zebra h3{margin:0;}
.set-zebra > *:hover{transform:none;box-shadow:none;}

.set-ruled:not(.et_pb_row){display:grid;grid-template-columns:1fr 1fr;gap:0 clamp(2rem,4vw,4rem);}
/* border:0 is deliberately not restated here: the watercolour block above
   already sets border-top on this selector, and it loads before this
   fragment, so a later border:0 shorthand here would zero that hairline out.
   The other sides need no reset; a div's default border is already none. */
.set-ruled > *{padding:1.7rem 0;background:transparent;border-radius:0;}
.set-ruled h3{margin-bottom:.5rem;}
.set-ruled > *:hover{transform:none;box-shadow:none;}

/* ---------------------------------------------------------------- lists */
ul.plain{list-style:none;}
ul.plain li,.prose ul li{padding-left:1.4rem;position:relative;margin-bottom:.5rem;}
/* The organic blob shape (border-radius, width, height, rotation) is already
   in the watercolour block above; without content/position/colour here that
   mask has nothing to apply to, so those properties are supplied here. */
ul.plain li::before,.prose ul li::before{content:"";position:absolute;left:0;top:.66em;
  background:var(--gcid-ahc-sage-mid);}
.prose ul{margin:.2rem 0 1.3rem;list-style:none;}
.prose p{margin-bottom:1.15rem;}
.prose h2{margin:2.6rem 0 .9rem;}
.prose h3{margin:2rem 0 .7rem;}

/* ---------------------------------------------------------------- policy pages */
/* Long-form policy pages: numbered sections, generous spacing, plain circular
   bullets. The source does not apply the organic-bullet mask here, so the
   plain circle stands, unlike ul.plain and .prose ul above. */
.policy h2{margin:2.8rem 0 .9rem;font-size:clamp(1.35rem,2.4vw,1.75rem);}
.policy h2:first-of-type{margin-top:1.4rem;}
.policy h3{margin:1.9rem 0 .6rem;font-size:1.12rem;}
.policy p,.policy li{max-width:70ch;}
.policy ul{list-style:none;margin:.3rem 0 1.2rem;}
.policy ul li{padding-left:1.4rem;position:relative;margin-bottom:.5rem;}
.policy ul li::before{content:"";position:absolute;left:0;top:.66em;width:7px;height:7px;
  border-radius:50%;background:var(--gcid-ahc-sage-mid);}
.policy .updated{font-size:.93rem;color:var(--gcid-ahc-ink-muted);}

/* ---------------------------------------------------------------- tables */
table{border-collapse:collapse;width:100%;margin:1.2rem 0 1.6rem;font-size:.98rem;}
th{text-align:left;background:var(--gcid-ahc-linen);color:var(--gcid-heading-color);
  font-family:'Inter Self-Hosted',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-weight:600;font-size:.82rem;letter-spacing:.06em;text-transform:uppercase;
  padding:.75rem .9rem;border-bottom:2px solid var(--gcid-ahc-sage-mid);}
td{padding:.8rem .9rem;border-bottom:1px solid var(--gcid-ahc-border-hairline);vertical-align:top;}
.band-card th{background:var(--gcid-ahc-cream);}

/* ---------------------------------------------------------------- article */
.artmeta{display:flex;flex-wrap:wrap;gap:.5rem 1.5rem;font-size:.93rem;color:var(--gcid-ahc-ink-muted);
  margin:1.2rem 0 0;align-items:center;}
/* Requested as ".contents"; the source's sticky-contents component is named
   .toc throughout, so the class name below is copied as-is from source. */
.toc{background:var(--gcid-ahc-cream);border-radius:10px;padding:1.5rem 1.7rem;margin:2rem 0;}
.toc h2{font-size:1.05rem;font-family:'Inter Self-Hosted',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-weight:600;color:var(--gcid-heading-color);letter-spacing:.06em;text-transform:uppercase;margin:0 0 .8rem;}
.toc ol{margin-left:1.1rem;font-size:1rem;}
.toc li{margin-bottom:.4rem;}
.toc a{display:block;padding:.42rem 0;text-decoration:none;color:var(--gcid-body-color);font-size:.97rem;
  border-left:2px solid transparent;padding-left:.8rem;transition:border-color .18s,color .18s;}
.toc a:hover{color:var(--gcid-heading-color);border-left-color:var(--gcid-ahc-sage-mid);}
.toc a.active{color:var(--gcid-heading-color);border-left-color:var(--gcid-primary-color);font-weight:500;}
.author{display:flex;gap:1.2rem;align-items:flex-start;background:var(--gcid-ahc-cream);border-radius:10px;
  padding:1.6rem 1.7rem;margin:2.6rem 0 0;}
.author img{width:76px;height:76px;border-radius:50%;object-fit:cover;flex:none;}
.author p{font-size:.98rem;}
.post{background:var(--gcid-ahc-cream);border-radius:10px;overflow:hidden;
  border:1px solid var(--gcid-ahc-border-hairline);display:flex;flex-direction:column;}
.post .thumb{background:var(--gcid-ahc-linen);}
.post .body{padding:1.4rem 1.5rem 1.6rem;display:flex;flex-direction:column;flex:1;}
.post h3{font-size:1.14rem;margin-bottom:.5rem;}
.post p{font-size:.97rem;margin-bottom:1rem;}
.post .more{margin-top:auto;font-size:.95rem;font-weight:500;}
.portrait img{width:100%;}

/* ---------------------------------------------------------------- card */
.card{background:var(--gcid-ahc-cream);border-radius:10px;padding:1.8rem 1.7rem;
  border:1px solid var(--gcid-ahc-border-hairline);}
.card.accent{border-left:4px solid var(--gcid-secondary-color);}
.card h3{margin-bottom:.55rem;}
.card p{font-size:1rem;}
.card .ico{margin-bottom:1rem;}

/* ---------------------------------------------------------------- fee */
.fee{background:var(--gcid-ahc-cream);border-radius:10px;padding:1.9rem 1.7rem;
  border:1px solid var(--gcid-ahc-border-hairline);display:flex;flex-direction:column;}
.fee.feature{border:2px solid var(--gcid-primary-color);}
.fee .amt{font-family:'Fraunces Self-Hosted',Georgia,'Times New Roman',serif;font-size:2.5rem;
  color:var(--gcid-heading-color);line-height:1;margin:.5rem 0 .2rem;}
.fee .per{font-size:.93rem;color:var(--gcid-ahc-ink-muted);margin-bottom:1.1rem;}
.fee ul{margin-bottom:1.5rem;}
.fee .btn{margin-top:auto;}

/* ---------------------------------------------------------------- card, fee, post hover lift */
.card,.step,.fee,.post{transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease;}
.card:hover,.step:hover,.fee:hover{transform:translateY(-3px);box-shadow:0 8px 22px var(--gcid-ahc-drop-shadow);}
.post:hover{transform:translateY(-3px);box-shadow:0 10px 26px var(--gcid-ahc-drop-shadow);
  border-color:var(--gcid-ahc-sage-mid);}

/* ---------------------------------------------------------------- footer */
footer{background:var(--gcid-ahc-cream);padding:clamp(2.6rem,5vw,3.6rem) 0 8.5rem;
  border-top:1px solid var(--gcid-ahc-border-hairline);font-size:.96rem;}
.ft{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:2.4rem;}
.ft h3{font-family:'Inter Self-Hosted',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:.78rem;font-weight:600;letter-spacing:.13em;text-transform:uppercase;
  color:var(--gcid-ahc-rose-deep);margin-bottom:.85rem;}
.ft ul{list-style:none;}
.ft li{margin-bottom:.45rem;}
.ft .logo svg{height:44px;width:auto;margin-bottom:1rem;}
.bacp{display:inline-block;margin-top:1rem;background:var(--gcid-secondary-color);color:var(--gcid-ahc-white);
  font-size:.8rem;font-weight:600;letter-spacing:.05em;padding:.45rem .85rem;border-radius:4px;}
/* Crisis signposting panel, added to the footer 7 September 2026 to satisfy
   WCAG 3.2.6 Consistent Help: same words, same place, on every page. Ships
   inside the same <footer> as .ft and .legal above and below it. */
.crisis{margin-top:2.2rem;padding-top:1.4rem;border-top:1px solid var(--gcid-ahc-border-hairline);}
.crisis p{font-size:.94rem;line-height:1.6;max-width:78ch;}
.crisis a{text-decoration:underline;text-underline-offset:2px;}
.legal{margin-top:1.6rem;padding-top:1.3rem;border-top:1px solid var(--gcid-ahc-border-hairline);
  font-size:.88rem;color:var(--gcid-ahc-ink-muted);display:flex;flex-wrap:wrap;gap:.6rem 1.6rem;}

/* ---------------------------------------------------------------- booking bar */
/* Fixed bar at the foot of the viewport, outside <footer> in the source
   markup though it ships on every page alongside it. footer's 8.5rem bottom
   padding above exists to clear this bar, which is why the two are kept
   together in this file. Not `.mockbar`: that class belongs only to the
   build tool's own "design mock-up, not a live page" banner in build_site.py
   and never appears in this child theme. */
.bar{position:fixed;left:0;right:0;bottom:0;z-index:50;background:var(--gcid-primary-color);color:var(--gcid-ahc-white);
  padding:.8rem var(--gut);display:flex;align-items:center;justify-content:center;gap:1.4rem;flex-wrap:wrap;}
.bar span{font-size:1rem;font-weight:500;}
.bar .btn{min-height:44px;padding:.55rem 1.3rem;font-size:.95rem;}
/* .btn above deliberately drops colour, background, padding and radius to
   Divi presets, but the bar's button is raw markup (class="btn btn-light"),
   not a Divi Button module, so nothing else in this theme supplies a preset
   for it. Padding is restated immediately above for the bar's smaller size;
   colour and background are supplied here, since .btn-light sits on the
   bar's dark terra background and needs a light fill to read against it. */
.btn-light{background:var(--gcid-ahc-cream);color:var(--gcid-heading-color);border-radius:6px;}
@media (max-width:560px){ .bar span{display:none;} .bar .btn{width:100%;} }

/* ---------------------------------------------------------------- mobile, 900px and below */
@media (max-width:900px){
  .ft,.defs{grid-template-columns:1fr;}
  .set-swatch:not(.et_pb_row),.set-ruled:not(.et_pb_row),.set-steps:not(.et_pb_row){grid-template-columns:1fr;}
  .set-zebra > *{grid-template-columns:1fr;gap:.5rem;}
  nav.main a:not(.btn){display:none;}
  .mobnav{display:block;margin-left:auto;}
  nav.main{display:none;}
  .hd{position:relative;}
  .author{flex-direction:column;}
}

@media (prefers-reduced-motion:reduce){
  .card:hover,.step:hover,.fee:hover,.post:hover{transform:none;}
  nav.main a:not(.btn)::after{transition:none;}
}

/* ============================================================================
   Part three: the desktop dropdown submenu, the mobile accordion and the
   breadcrumb trail. These are not in site_system.py at all and were missed on
   the first pass through that file for exactly that reason: they were built
   the evening of 7 September 2026 in build_site.py itself, as the NAV_CSS and
   CRUMB_CSS string constants, because the submenu, accordion and crumbs are
   bespoke components of this build rather than anything Divi generates.
   Declarations are copied as they stand there; colours are mapped to the same
   Divi Design Variables as the rest of this file, per the build spec's colour
   table, sizes and spacing stay literal, and font stacks are written out in
   full for the same reason as elsewhere in this file. Every media query is
   kept, including both reduced-motion blocks: the submenu's hover slide and
   the accordion's chevron rotation are each a separate piece of motion and
   each needs its own opt-out.
   ============================================================================ */

/* ---------------------------------------------------------------- desktop submenu */
/* Opens on hover and on focus, and its links stay in the tab order either
   way, so it is reachable by keyboard with no script. On touch, hover does
   not fire, which is why every child is also listed flat in the mobile panel
   rather than nested behind a tap. */
.main .has-sub{position:relative;}
.main .has-sub>.sub{position:absolute;left:0;top:100%;min-width:16.5rem;z-index:60;
  background:var(--gcid-ahc-cream);border:1px solid var(--gcid-ahc-border-hairline);border-radius:10px;
  box-shadow:0 12px 26px var(--gcid-ahc-drop-shadow);padding:.45rem;margin-top:.4rem;
  display:flex;flex-direction:column;gap:.1rem;
  opacity:0;visibility:hidden;transform:translateY(4px);
  transition:opacity .14s ease,transform .14s ease,visibility .14s;}
/* The gap between the parent and the panel would drop the hover on the way
   down, so the parent carries an invisible bridge across it rather than the
   panel sitting flush. */
.main .has-sub::after{content:"";position:absolute;left:0;right:0;top:100%;height:.5rem;}
.main .has-sub:hover>.sub,.main .has-sub:focus-within>.sub{
  opacity:1;visibility:visible;transform:translateY(0);}
.main .sub a{display:block;padding:.55rem .7rem;border-radius:7px;font-size:.95rem;
  line-height:1.35;color:var(--gcid-body-color);white-space:normal;}
.main .sub a:hover,.main .sub a:focus-visible{background:var(--gcid-ahc-linen);}
.main .sub a.self{font-weight:600;margin-bottom:.3rem;padding-bottom:.65rem;
  border-bottom:1px solid var(--gcid-ahc-border-hairline);border-radius:7px 7px 0 0;}
@media (prefers-reduced-motion:reduce){.main .has-sub>.sub{transition:none;}}

/* ---------------------------------------------------------------- mobile accordion */
/* Specificity note, carried over from build_site.py's own comment at the
   equivalent point in NAV_CSS. The base rule for every mobile-panel link is
   `.mobnav .panel-nav a:not(.btn)` earlier in this file, three classes and an
   element, and it puts a border-bottom divider on every row for the flat top
   level. Anything lighter than that weight loses to it silently, which is
   how an earlier version of this build shipped with every accordion child
   still carrying the divider meant for top-level rows. The rules below are
   written to match that selector's weight and are placed after it in this
   file, so they win on source order rather than on specificity, exactly as
   build_site.py requires. They must stay below the base
   `.mobnav .panel-nav a:not(.btn)` rule, not above it. */
.mobnav .panel-nav details.acc{border-bottom:1px solid var(--gcid-ahc-border-hairline-faint);}
.mobnav .panel-nav details.acc summary{list-style:none;display:flex;align-items:center;
  justify-content:space-between;gap:1rem;padding:.78rem 0;min-height:46px;
  font-family:'Inter Self-Hosted',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-weight:600;font-size:1.05rem;color:var(--gcid-body-color);cursor:pointer;}
.mobnav .panel-nav details.acc summary::-webkit-details-marker{display:none;}
.mobnav .panel-nav details.acc summary::after{content:"";width:9px;height:9px;flex:none;
  margin-right:.2rem;border-right:2px solid var(--gcid-ahc-sage-mid);border-bottom:2px solid var(--gcid-ahc-sage-mid);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .15s;}
.mobnav .panel-nav details.acc[open] summary::after{transform:rotate(-135deg) translate(-3px,-3px);}
.mobnav .panel-nav details.acc summary:focus-visible{outline:2px solid var(--gcid-heading-color);
  outline-offset:2px;border-radius:4px;}
.mobnav .panel-nav .accbody{padding-bottom:.4rem;}
.mobnav .panel-nav .accbody a:not(.btn){padding:.5rem 0 .5rem 1.35rem;min-height:44px;
  font-size:.98rem;font-weight:400;border-bottom:0;}
.mobnav .panel-nav .accbody a:not(.btn).self{font-weight:600;}
@media (prefers-reduced-motion:reduce){
  .mobnav .panel-nav details.acc summary::after{transition:none;}}

/* A menu taller than the screen must be able to scroll on its own. The panel
   is absolutely positioned inside a sticky header, so on a short page (the
   404, the accessibility statement) there is not enough page behind it to
   scroll the tail of the list into view, and the last items, including the
   booking button, would simply be unreachable. */
.mobnav .panel-nav{max-height:calc(100vh - 5.5rem);max-height:calc(100dvh - 5.5rem);
  overflow-y:auto;-webkit-overflow-scrolling:touch;}

/* ---------------------------------------------------------------- breadcrumbs */
.crumbs{background:var(--gcid-ahc-linen);border-bottom:1px solid var(--gcid-ahc-border-hairline);}
.crumbs ol{list-style:none;margin:0;padding:.85rem 0;display:flex;flex-wrap:wrap;
  gap:.2rem .55rem;font-size:.92rem;line-height:1.5;}
.crumbs li{display:flex;align-items:center;gap:.55rem;color:var(--gcid-body-color);}
.crumbs li+li::before{content:"";width:5px;height:5px;border-right:1.5px solid var(--gcid-ahc-sage-mid);
  border-bottom:1.5px solid var(--gcid-ahc-sage-mid);transform:rotate(-45deg);flex:none;}
.crumbs a{color:var(--gcid-heading-color);text-decoration:underline;text-underline-offset:2px;}
.crumbs a:hover{color:var(--gcid-body-color);}
.crumbs [aria-current]{color:var(--gcid-body-color);}
@media (max-width:640px){.crumbs ol{padding:.7rem 0;font-size:.88rem;}}

/* ============================================================================
   Part four, 8 September 2026. Two faults found by comparing the built pages
   against the mock-ups side by side.
   ============================================================================ */

/* 1. Button fills. Part two dropped colour, background, padding and radius on
   the grounds that Divi presets supply them. That holds only for Divi Button
   modules, which carry .et_pb_button. Every button in the header, the footer,
   the mobile panel and the booking bar is raw markup carrying .btn, so no
   preset ever reaches it and they rendered as bare text. The two class sets
   do not collide, so the presets still own the Button modules. */
.btn{padding:.85rem 1.6rem;border-radius:6px;}
.btn-primary{background:var(--gcid-primary-color);color:var(--gcid-ahc-white);}
.btn-primary:hover{background:var(--gcid-heading-color);color:var(--gcid-ahc-white);}
.btn-secondary{background:var(--gcid-secondary-color);color:var(--gcid-ahc-white);}
.btn-secondary:hover{background:var(--gcid-ahc-sage-mid);color:var(--gcid-ahc-white);}
.btn-ghost{background:transparent;color:var(--gcid-heading-color);
  box-shadow:inset 0 0 0 1.6px var(--gcid-heading-color);}
.btn-ghost:hover{background:var(--gcid-ahc-ghost-button-hover);color:var(--gcid-heading-color);}

/* 2. Breadcrumb band height. In the mock-ups the crumbs are a bare div between
   the header and the first section, so they never take a section's vertical
   padding. In the Divi build they sit inside a section, which added 54px top
   and bottom and pushed the band to roughly three times its designed height,
   with its own border-bottom stranded in the middle of it. The crumbs supply
   their own padding of .85rem, so the section around them takes none. */
.et_pb_section:has(.crumbs){padding-top:0;padding-bottom:0;}

/* ============================================================================
   Part five, 8 September 2026. Divi's own single-post header.
   ============================================================================ */

/* On a single post Divi prints its own title block above the layout, as an h1 with class
   .entry-title inside .et_post_meta_wrapper. The built posts carry their own h1, byline and
   date, because the mock-ups were designed with them, so every post rendered with two h1
   elements and a duplicated title. Two h1s is a heading-order fault, not just a visual one.

   The Divi-native fix is a Theme Builder body template assigned to all posts, carrying only
   a Post Content module. That is the better answer if the template assignment values are
   ever confirmed: the condition strings for assign-template are not documented and were not
   worth guessing at on a live site. Suppressing the wrapper does the same job here, is
   scoped to single posts only, and comes out in one line if the template is built later.

   display:none removes the duplicate from the accessibility tree as well as the page, so
   the remaining h1 is the real one and the heading order is correct. */
/* superseded by part eight, which scopes this with :has() */

/* ============================================================================
   Part six, 8 September 2026. Container classes restored on the built pages.
   ============================================================================ */

/* The generator used to strip the grid container's own class when it turned that container
   into a Divi row, on the reasoning that Divi supplies the columns. It does, but the class
   also carries the treatment: the deckle mask and rotation on .set-swatch, the alternating
   tint on .set-zebra, the hairlines on .set-ruled, the numerals on .set-steps. Measured
   against the mock-ups, four of the fifteen treatments had nothing to attach to on any page,
   and 18 .cta-row wrappers had vanished.

   The class is kept now, so the two layout systems have to agree. Divi's row owns the
   columns, so the grid declarations above are scoped away from a Divi row with
   :not(.et_pb_row) and everything else in those rules still applies. */

/* .cta-row now ships as its own markup inside a Code module, so it is a plain div and lays
   its buttons out itself. Its buttons are raw markup, styled by the .btn rules in part four
   rather than by a preset, exactly as the header, footer and booking-bar buttons are. */
.cta-row{display:flex;flex-wrap:wrap;gap:.85rem;margin:1.6rem 0 1rem;}
.cta-row .btn{flex:0 0 auto;}

/* ============================================================================
   Part seven, 8 September 2026. Zebra striping, marked rather than counted.
   ============================================================================ */

/* In the mock-ups the zebra items are siblings inside one .set-zebra, so
   .set-zebra > *:nth-child(odd) picks out every other one. In the Divi build each item is a
   separate top-level row with no shared parent, so nth-child has nothing to count against
   and the striping was absent from all seven pages that use it. The generator now marks the
   alternation explicitly at build time, which is deterministic and does not depend on how
   Divi happens to nest its rows.

   .set-zebra is deliberately not carried onto the row: its own "> *" rule would then apply
   the heading-beside-prose grid to each of the two Divi columns instead of to the pair. */
.zebra-row{padding:1.5rem clamp(1rem,3vw,2.2rem);border-radius:6px;}
.zebra-odd{background:var(--gcid-ahc-cream);}
.band-card .zebra-odd{background:var(--gcid-ahc-linen);}

/* ============================================================================
   Part eight, 8 September 2026. The post-header suppression, scoped properly.
   ============================================================================ */

/* Part five hid Divi's own single-post title block outright, because the rebuilt posts carry
   their own h1 and were rendering two. That was too broad. The three 2019 posts still awaiting
   their 301s have no h1 of their own, so hiding Divi's left them with none at all, which a
   heading-order check caught and a person would not have.

   Scoped now to posts whose layout supplies its own h1. :has() is well supported and is what
   makes this expressible in CSS at all; without it this would need a body class from PHP. */
body.single-post:has(.et_pb_section h1) .et_post_meta_wrapper{display:none;}

/* ============================================================================
   Part nine, 8 September 2026. The palette, declared here rather than assumed.
   ============================================================================ */

/* Divi emits a colour's CSS custom property only when a module on that page uses it. The five
   pre-generated slots are always present, and a custom colour is present only if some module
   happens to reference it. A child stylesheet is not a module, so on a typical built page 11
   of the 19 palette variables did not resolve at all, while this file referenced them 62
   times.

   An unresolved var() is not a no-op. The declaration becomes invalid at computed-value time
   and the property falls back to its inherited value, so white button text quietly became
   charcoal on terracotta at 2.52:1, hairlines vanished, and every drop shadow disappeared.
   Nothing errored and nothing looked obviously broken, which is why it survived a clean
   selector audit: the selectors matched, the values did not arrive.

   Declaring the palette here removes the dependency. Divi's variable store stays the source
   of truth for anyone working in the builder; this block mirrors it for the stylesheet, and
   the two must be changed together. The relative tints derive from the base colours above
   them, so a palette change still propagates through this file. */
:root{
  --gcid-primary-color:#A9593C;
  --gcid-secondary-color:#5D7E5F;
  --gcid-heading-color:#8F4B33;
  --gcid-body-color:#333333;
  --gcid-link-color:var(--gcid-heading-color);
  --gcid-ahc-linen:#F1E0CE;
  --gcid-ahc-cream:#FAF4EC;
  --gcid-ahc-sage-light:#A5BDA7;
  --gcid-ahc-sage-mid:#658A69;
  --gcid-ahc-rose-light:#D59A9A;
  --gcid-ahc-rose-deep:#9C4141;
  --gcid-ahc-ink-muted:#5B4C40;
  --gcid-ahc-white:#FFFFFF;
  --gcid-ahc-border-hairline:rgba(101,138,105,.30);
  --gcid-ahc-border-hairline-strong:rgba(101,138,105,.42);
  --gcid-ahc-border-hairline-faint:rgba(101,138,105,.22);
  --gcid-ahc-drop-shadow:rgba(51,51,51,.09);
  --gcid-ahc-ghost-button-hover:rgba(143,75,51,.07);
  --gcid-ahc-link-wash-hover:rgba(156,65,65,.28);
}

/* ============================================================================
   Part ten, 8 September 2026. The schema section, which renders as empty space.
   ============================================================================ */

/* Each page carries its JSON-LD in a Code module, which outputs a <script> and nothing
   visible. Divi still gives that module a section and a row, and the section takes the
   standard 54px of vertical padding, so every page opened with a 109px band of nothing
   between the header and the breadcrumbs. It looks like a layout bug and it is really an
   invisible module in a visible container.

   Collapsed here rather than in the generator, so it holds for any page that carries schema
   this way, including ones built later by hand in the builder. */
.et_pb_section:has(> .et_pb_row > .et_pb_column > .ld-json){
  padding-top:0;padding-bottom:0;
}
.et_pb_section:has(> .et_pb_row > .et_pb_column > .ld-json) .et_pb_row{
  padding-top:0;padding-bottom:0;
}

/* ============================================================================
   Part eleven, 8 September 2026. WCAG 1.4.10 Reflow, ported from the mock-ups.
   ============================================================================ */

/* This block existed in site_system.py and was missed on the first pass through it. Measuring
   the built pages at 320px found the same fault it was written to fix: the comparison and
   cookie tables are about 408px at their minimum, so they widened the whole column and the
   body copy scrolled sideways with them. 1.4.10 exempts content that genuinely needs a
   two-dimensional layout, which covers a table; it does not cover the prose beside it.

   Scoped to #et-boc as well as main, because Divi wraps page content in #et-boc and a Theme
   Builder layout may not emit a <main> at all. */
@media (max-width:900px){
  .artgrid{grid-template-columns:minmax(0,1fr);}
  .artgrid > *{min-width:0;}
  /* Every table, not only those inside .prose or .policy: the privacy policy's own table
     sits outside both. */
  /* !important is deliberate and is the exception, not the habit. Divi styles tables with a
     selector chain that outranks #et-boc table, so without it the rule matched and lost, and
     the table stayed 408px wide inside a 305px viewport. This is a WCAG 1.4.10 fix, not a
     preference. */
  #et-boc table, main table{display:block!important;overflow-x:auto!important;max-width:100%!important;width:max-content!important;}
  #et-boc code, main code{overflow-wrap:anywhere;}
  /* A 30-character email address is 281px wide at this size and has no break opportunity in
     it, so it is the one string on the site long enough to overflow 320px by itself. */
  #et-boc a[href^="mailto:"], #et-boc a[href^="http"],
  main a[href^="mailto:"], main a[href^="http"]{overflow-wrap:anywhere;}
  /* Divi's own row and column keep a minimum width from their content unless told otherwise,
     which is what lets a wide child push the whole page sideways. */
  .et_pb_row, .et_pb_column{min-width:0;}
}

/* ------------------------------------------------------------------------- *
 * Part twelve. Mobile stacking, WCAG 2.2 AA 1.4.10 Reflow.
 *
 * Added 8 September 2026. Divi 5 did not stack multi-column rows on this build.
 * At a 320px viewport the homepage hero row stayed 305px wide while its column
 * was 109px, so a 250px button inside it pushed the document to 426px and the
 * page scrolled sideways. Single-column rows were unaffected, which is why the
 * fault only showed on some pages and why the 390px pass missed it.
 *
 * The layouts were generated through the REST API and carry no per-breakpoint
 * column settings, which is what Divi normally stacks from. Rather than write
 * responsive settings into 23 layouts, the behaviour is asserted once here.
 * 767px matches Divi's own phone breakpoint.
 * ------------------------------------------------------------------------- */
@media (max-width:767.98px){
  #et-boc .et_pb_row.et_flex_row{flex-direction:column;}
  #et-boc .et_pb_row.et_flex_row > .et_pb_column{width:100%;max-width:100%;}

  /* The CTA pair sits side by side above this width. Wrapping alone is not
     enough: each button is sized by its own text, so it must also be allowed
     to shrink and to break its label across lines. */
  .cta-row{flex-wrap:wrap;}
  .cta-row > .btn,
  .cta-row > a{max-width:100%;white-space:normal;}
}

/* ------------------------------------------------------------------------- *
 * Part thirteen. The portrait blocks stop bleeding sideways on phones.
 *
 * Added 8 September 2026. .portrait::before and ::after are the two offset
 * watercolour blocks behind Amy's photograph. They sit 14px outside the image
 * on purpose, which reads as a hand-placed paper edge. On desktop the column
 * is inset from the viewport so the bleed has room. At 320px the column
 * already reaches the viewport edge, so the outward 14px pushed the document
 * to 315px and the whole page scrolled sideways. It showed on the homepage and
 * the about page only, because they are the only two pages carrying .portrait.
 *
 * Only the horizontal bleed is removed. The vertical offset stays, so the
 * blocks still sit proud above and below and the treatment survives the
 * breakpoint rather than being switched off.
 * ------------------------------------------------------------------------- */
@media (max-width:767.98px){
  .portrait::before{inset:-14px 66% 70% 0;}
  .portrait::after{inset:38% 0 -14px 42%;}
}

/* ------------------------------------------------------------------------- *
 * Part fourteen. The trust strip, which was never ported.
 *
 * Added 8 September 2026, after Alex spotted the icons sitting on the text
 * baseline with the label wrapping underneath them.
 *
 * Two faults, one cause. The mock-up builds this as .trust ul > li, a centred
 * flex row per item with the icon locked beside the label. The generator turned
 * each item into its own Blurb module with the SVG inline inside a <p>, so the
 * ul and li disappeared, these rules had nothing to match, and the icons fell
 * back to being inline images on the baseline. Then the rules themselves were
 * never carried over from site_system.py either, so even the markup would not
 * have saved it.
 *
 * Fixed on both sides: the 11 pages carrying the strip now hold the mock-up's
 * own ul markup in a single Code module, the same decision already taken for
 * .cta-row and the header and footer, and these are the mock-up's rules.
 *
 * Not Divi's Blurb icon field. That takes an ETmodules glyph or an uploaded
 * image, and these are bespoke line icons that inherit currentColor. Divi's
 * icon set would have changed the drawing, and images would have cost eight
 * more media files and lost the colour inheritance.
 * ------------------------------------------------------------------------- */
#et-boc .trust ul,
.trust ul{
  list-style:none;
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:.7rem 2.3rem;
  margin:0;
  padding:1.15rem 0;
  font-size:.95rem;
}
#et-boc .trust li,
.trust li{
  display:flex;
  align-items:center;
  gap:.6rem;
  margin:0;
  padding:0;
  list-style:none;
}
.trust li svg{flex:none;}

/* The section background is set on the Divi module. Only the hairlines are
   missing, and they are the same sage 30% used everywhere else. */
.trust{
  border-top:1px solid var(--gcid-ahc-border-hairline);
  border-bottom:1px solid var(--gcid-ahc-border-hairline);
}

@media (max-width:900px){
  /* Centred, the longest item wraps to two lines and a vertically centred icon
     then floats at the midpoint of the block instead of sitting with the first
     line. Align to the top and nudge the icon onto the first baseline. */
  #et-boc .trust li,
  .trust li{align-items:flex-start;}
  .trust li svg{margin-top:.2em;}
}

/* ------------------------------------------------------------------------- *
 * Part fifteen. Text colour on the coloured bands, which was never ported.
 *
 * Added 8 September 2026, found by a contrast pass rather than by eye.
 *
 * The band backgrounds are set as Divi module attributes, so the bands looked
 * right. The text colour rules that go with them live in site_system.py and
 * never came across, so every band kept the global heading and body colours.
 * On .band-deep that put terracotta #8F4B33 headings on deep sage #5D7E5F at
 * 1.43:1 and charcoal body copy at 2.78:1, against a WCAG 2.2 AA requirement
 * of 3:1 and 4.5:1. It reads as a slightly muddy heading, not as a fault,
 * which is exactly why it survived every visual check until it was measured.
 *
 * Only the decorative half of the band rules had been ported: the ::before
 * wash and the painted underline. Worth remembering that a partially ported
 * component looks finished.
 * ------------------------------------------------------------------------- */

/* Deep sage. Everything reverses out to white. */
#et-boc .band-deep,
.band-deep{color:var(--gcid-ahc-white);}
#et-boc .band-deep h2, #et-boc .band-deep h3, #et-boc .band-deep h4,
#et-boc .band-deep p,  #et-boc .band-deep li, #et-boc .band-deep .eyebrow,
.band-deep h2, .band-deep h3, .band-deep h4,
.band-deep p,  .band-deep li, .band-deep .eyebrow{color:var(--gcid-ahc-white);}

/* Light sage and rose are light enough to keep dark text, but not light enough
   for the terracotta heading colour, so headings drop to charcoal. */
#et-boc .band-sage h2, #et-boc .band-sage h3, #et-boc .band-sage h4,
#et-boc .band-sage .eyebrow, #et-boc .band-sage a:not(.btn),
#et-boc .band-rose h2, #et-boc .band-rose h3, #et-boc .band-rose h4,
#et-boc .band-rose .eyebrow, #et-boc .band-rose a:not(.btn),
.band-sage h2, .band-sage h3, .band-sage h4,
.band-sage .eyebrow, .band-sage a:not(.btn),
.band-rose h2, .band-rose h3, .band-rose h4,
.band-rose .eyebrow, .band-rose a:not(.btn){color:var(--gcid-body-color);}

.band-sage a:not(.btn):hover,
.band-rose a:not(.btn):hover{color:#1f1f1f;}

/* ------------------------------------------------------------------------- *
 * Part sixteen. Buttons keep their own colour inside a Text module.
 *
 * Added 8 September 2026, found by the contrast pass at 1.3:1.
 *
 * Divi's Text module preset emits
 *   .preset--module--divi-text--default a{color:var(--gcid-heading-color)}
 * which is (0,2,1) and beats .btn-primary at (0,1,0). Any button written as
 * markup inside a Text module therefore took the link colour: terracotta text
 * on the terracotta button fill, 1.3:1, effectively invisible. It only showed
 * on in-content buttons, because the header and footer buttons live in Code
 * modules that the Text preset never touches. That is why the earlier button
 * fix looked complete.
 *
 * Answered with an id rather than !important. #et-boc wraps all builder output,
 * so (1,2,1) beats the preset cleanly and still loses to anything deliberately
 * marked important later. The rules restate the same values as the .btn classes
 * above rather than inventing new ones, so there is one source of truth for the
 * palette and this block only settles which selector wins.
 * ------------------------------------------------------------------------- */
#et-boc a.btn-primary{color:var(--gcid-ahc-white);}
#et-boc a.btn-primary:hover{color:var(--gcid-ahc-white);}
#et-boc a.btn-secondary{color:var(--gcid-ahc-white);}
#et-boc a.btn-secondary:hover{color:var(--gcid-ahc-white);}
#et-boc a.btn-light{color:var(--gcid-heading-color);}
#et-boc a.btn-ghost{color:var(--gcid-heading-color);}
#et-boc a.btn-ghost:hover{color:var(--gcid-heading-color);}

/* On the deep sage band the ghost and light buttons sit on #5D7E5F, where the
   terracotta label would fail. They reverse out, as they do in the mock-up. */
#et-boc .band-deep a.btn-ghost,
#et-boc .band-deep a.btn-ghost:hover{color:var(--gcid-ahc-white);}

/* ------------------------------------------------------------------------- *
 * Part seventeen. The swatch tilt stops overflowing on phones.
 *
 * Added 8 September 2026. .set-swatch > *:nth-child(2n) rotates -0.5deg and
 * 3n rotates 0.6deg, which is the hand-placed look. In the mock-up those
 * children are small cards in a grid. After the Divi conversion the class sits
 * on a row and its children are the columns, so the tilt lands on a full-width
 * column instead. 6.8g3 again, in a form that only shows at one breakpoint.
 *
 * A rotated box's bounding box is wider than the box. At 320 and 390 the
 * columns are 100% wide, so half a degree pushed 0.8px past each edge and the
 * page scrolled sideways by 2px. Just enough for a scrollbar, not enough to
 * see, which is why it survived until it was measured.
 *
 * The tilt moves inward rather than off. The module inside the column is
 * narrower than the column by its 25.6px of padding, so the rotated bounding
 * box has room and the character survives the breakpoint.
 * ------------------------------------------------------------------------- */
@media (max-width:767.98px){
  #et-boc .set-swatch > .et_pb_column{rotate:0deg;}
  #et-boc .set-swatch > .et_pb_column:nth-child(2n) > .et_pb_module{rotate:-.5deg;}
  #et-boc .set-swatch > .et_pb_column:nth-child(3n) > .et_pb_module{rotate:.6deg;}
}

/* ------------------------------------------------------------------------- *
 * Part eighteen. A visible focus indicator, which Divi removes.
 *
 * Added 8 September 2026. WCAG 2.2 AA, 2.4.7 Focus Visible and 2.4.11 Focus
 * Appearance. Divi sets outline:none on focus, and the child theme had only
 * ever restored an indicator on the mobile accordion summary. Every one of the
 * 34 interactive elements on the contact page computed outline-style:none when
 * focused, so a keyboard user had no way to tell where they were. On a site
 * whose audience is explicitly neurodivergent, that is not a minor finding.
 *
 * :focus-visible rather than :focus, so a mouse click does not leave a ring
 * behind but Tab always shows one.
 *
 * Two rings, not one. A single charcoal outline meets 3:1 against the cream
 * and white grounds but not against .band-deep's #5D7E5F or the terracotta
 * button fill. The white box-shadow sits between the element and the outline,
 * so on light grounds it is invisible and the charcoal reads, and on dark
 * grounds the white reads. One rule that works on every background on the
 * site, rather than a list of per-band exceptions to keep in step.
 *
 * The #et-boc copies are there because Divi's own reset is specific enough to
 * win against the bare element selectors on builder output.
 * ------------------------------------------------------------------------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
#et-boc a:focus-visible,
#et-boc button:focus-visible,
#et-boc input:focus-visible,
#et-boc select:focus-visible,
#et-boc textarea:focus-visible,
#et-boc summary:focus-visible,
#et-boc [tabindex]:focus-visible{
  outline:3px solid var(--gcid-body-color);
  outline-offset:2px;
  box-shadow:0 0 0 2px var(--gcid-ahc-white);
  border-radius:2px;
}

/* Anything that opts out of the ring must still show focus some other way.
   Nothing on the site does at present; this is here so that a future
   outline:none has to make a deliberate choice rather than inherit one. */

/* ------------------------------------------------------------------------- *
 * Part nineteen. Header and footer row sizing, stated rather than assumed.
 *
 * Added 8 September 2026, found while building the 404.
 *
 * Divi writes the Theme Builder row's width into a per-request dynamic
 * stylesheet. On a normal page that file carries it and the header spans the
 * full width to a 1180px measure, as designed. On a URL that does not resolve
 * to a real post, Divi enqueues only et-divi-dynamic-tb-<header>-<footer>.css
 * and the row falls back to Divi's own defaults: 80% wide, 1080px maximum. The
 * page's own URL rendered correctly the whole time, which is exactly what made
 * it look like a 404 bug rather than an asset one.
 *
 * The visible symptom was the header row at 244px inside a 305px viewport, so
 * the right-aligned mobile menu sat 30px outside it and every 404 scrolled
 * sideways.
 *
 * Same lesson as part nine and the palette. Anything the design depends on has
 * to be stated in this file rather than left to Divi to emit, because Divi only
 * emits it in the contexts it expects. Moving the query swap earlier, to wp
 * priority 1, did not help: the asset decision is made earlier still.
 * ------------------------------------------------------------------------- */
.et-l--header .et_pb_row,
.et-l--footer .et_pb_row{
  width:100%;
  max-width:1180px;
}

/* ------------------------------------------------------------------------- *
 * Part twenty. The hero, which Divi cannot lay out from its row structure.
 *
 * Added 8 September 2026, after Alex said the hero images do not sit like the
 * mock-ups on desktop. They did not.
 *
 * The mock-up hero is .hero-grid{grid-template-columns:2fr 3fr}, portrait left
 * at two fifths, copy right at three fifths, vertically centred on each other.
 * The layouts were generated with a "2_5,3_5" row and the comment in
 * site_system.py says every ratio in the design is a native Divi 5 structure.
 * That comment is wrong, and this is the one it is wrong about.
 *
 * Divi 5 lays a row out in twenty-fourths. Halves, thirds, quarters, sixths,
 * eighths and twelfths all land on an integer; fifths do not, because 2/5 of 24
 * is 9.6. Given a structure it cannot express, Divi does not fail and does not
 * warn. It emits et_flex_column_24_24 on both columns, each of them full width,
 * and the flex row then shares the space equally. So the hero rendered 50/50
 * with the copy top-aligned beside a much taller portrait, and the heading
 * wrapped to four lines that should have been three.
 *
 * flex rather than width, because 2 and 3 against a flex-basis of zero divides
 * the space left after the gap in exactly the ratio the grid did, and needs no
 * arithmetic against Divi's own gutter variable. width:auto is there to beat
 * Divi's calc() on the column, and min-width:0 so a long word cannot push the
 * column wider than its share.
 *
 * Above 767px only. Below it, part twelve stacks the row and both columns go
 * full width, which is what the mock-up does too.
 * ------------------------------------------------------------------------- */
@media (min-width:768px){
  #et-boc .hero-grid.et_pb_row{align-items:center;}
  #et-boc .hero-grid.et_pb_row > .et_pb_column{width:auto;min-width:0;flex:2 1 0;}
  #et-boc .hero-grid.et_pb_row > .et_pb_column + .et_pb_column{flex:3 1 0;}
}

/* The hero section took Divi's default 54px top and bottom. The design asks for
   more room above the fold and less below it, which is what separates the hero
   from the trust strip under it. */
#et-boc .hero-sec.et_pb_section{
  padding-top:clamp(2.6rem,6vw,4.6rem);
  padding-bottom:clamp(2rem,4vw,3rem);
}

/* The service page heroes are .wrap.g2, and the mock-up centres them with an
   inline style on that div. Inline styles do not survive the conversion, and
   the .g2 grid rule cannot apply to a Divi flex row, so the copy sat top
   aligned against a much taller image. Scoped to the hero so the other g2 rows
   on the site keep their align-items:start. */
@media (min-width:768px){
  #et-boc .hero-sec .et_pb_row.g2{align-items:center;}
}

/* ------------------------------------------------------------------------- *
 * Part twenty-one. The motion layer, which was never ported.
 *
 * Added 8 September 2026, after Alex said the heroes do not behave like the
 * mock-ups. They did not, because two of the five motion behaviours never came
 * across from MOTION_CSS and MOTION_JS. The sticky header shrink, the card
 * hover lift and the reading progress bar were ported. Scroll reveal and drift
 * were not, so every .rv class on all 25 URLs, and every .drift on the service
 * page heroes, has been inert since the build.
 *
 * READ THIS BEFORE CHANGING THE .rv RULE.
 *
 * The hidden state is scoped to html.js and nothing else. The class is set by
 * the script that also does the revealing, so the two cannot come apart. If the
 * script is blocked, fails, or is stripped, the class is never added, the rule
 * never matches and the page renders in full without animation. That is the
 * correct way round.
 *
 * The unscoped form of this rule caused a real failure on the mock-ups on
 * 7 September: .rv defaulted to opacity:0 with no fallback, and a page whose
 * script did not run showed a header, a footer and nothing in between, 5 to 56
 * invisible blocks, with no error and no clue. NHS, local authority and school
 * networks strip scripts, and so do content blockers. Never restore the
 * unscoped form.
 *
 * prefers-reduced-motion is handled in the script rather than here, because the
 * reduced-motion path has to reveal the content, not merely stop animating it.
 * ------------------------------------------------------------------------- */
html.js .rv{
  opacity:0;
  transform:translateY(14px);
  filter:blur(6px);
  transition:opacity .72s cubic-bezier(.22,.61,.36,1),
             transform .72s cubic-bezier(.22,.61,.36,1),
             filter .72s cubic-bezier(.22,.61,.36,1);
}
html.js .rv.in{opacity:1;transform:none;filter:blur(0);}
.rv-d1{transition-delay:.09s;}
.rv-d2{transition-delay:.18s;}
.rv-d3{transition-delay:.27s;}

/* Drift. The scroll-linked vertical offset on the service page hero images. The
   script writes the transform; this only warns the compositor. */
.drift{will-change:transform;}

@media (prefers-reduced-motion: reduce){
  html.js .rv{opacity:1;transform:none;filter:none;transition:none;}
  .drift{will-change:auto;transform:none!important;}
}

/* ------------------------------------------------------------------------- *
 * Part twenty-two. The skip link, and a hover state for the zebra rows.
 *
 * Added 8 September 2026 during the micro-interaction audit.
 *
 * WCAG 2.2 A, 2.4.1 Bypass Blocks. Every one of the 24 mock-ups carries
 * a skip link as the first thing in the body, and not one of the 25 built URLs
 * had it. A keyboard user had to tab through the whole header, including every
 * item of the open submenu, on every page. The rule was in site_system.py the
 * whole time with nothing to match.
 *
 * It targets #main-content, which Divi outputs on every template, rather than
 * the mock-ups' #main, which Divi never emits. The built pages have no <main>
 * element at all, so there is no main landmark either. That is a separate gap
 * and is recorded rather than papered over here.
 *
 * Visible on focus only, and it must never be display:none or a screen reader
 * will skip it too. Off-screen positioning is what keeps it available.
 * ------------------------------------------------------------------------- */
.skip{position:absolute;left:-9999px;}
.skip:focus,
.skip:focus-visible{
  position:fixed;
  left:1rem;
  top:1rem;
  z-index:99;
  background:var(--gcid-ahc-cream);
  color:var(--gcid-heading-color);
  padding:.7rem 1.1rem;
  border-radius:5px;
  box-shadow:0 2px 16px var(--gcid-ahc-drop-shadow);
}

/* The mock-up gives the zebra rows a hover lift through .set-zebra > *:hover.
   That selector cannot match here: nth-child does not survive the conversion,
   so part seven marks the alternation with explicit .zebra-row classes and
   .set-zebra never reaches the page. Same treatment, selector that exists. */
.zebra-row{transition:transform .18s ease, box-shadow .18s ease;}
.zebra-row:hover{transform:translateY(-3px);box-shadow:0 8px 22px var(--gcid-ahc-drop-shadow);}

/* ------------------------------------------------------------------------- *
 * Part twenty-three. The trust strip wraps two by two, not three and one.
 *
 * Added 8 September 2026, after Alex said the fourth item looked odd on its own
 * line. It did, and it is not a build fault: the mock-up has the same rule, the
 * same 1180px measure and the same copy, so it orphans the fourth item too.
 *
 * Measured at 1440px, the four items plus three 37px gaps need:
 *   contact 1125  (fits)      trauma 1192      counselling 1219
 *   supervision 1234          home 1375        about 1526
 * against 1180px of room. Only the contact page fits on one line, and the about
 * page is 346px over because one item, the supervision certificate, is 506px on
 * its own. No gap or type-size tweak reaches that, so wrapping is permanent and
 * the only question is whether it looks deliberate.
 *
 * Two by two does. Three and one reads as an accident, which is exactly how it
 * was reported. The cost is the contact page, which would have fitted on one
 * line and now matches everything else instead.
 *
 * The alternative is shortening two strings in Amy's copy. That is a content
 * decision, not a CSS one, so it is recorded rather than taken.
 * ------------------------------------------------------------------------- */
@media (min-width:768px){
  #et-boc .trust ul,
  .trust ul{
    display:grid;
    grid-template-columns:repeat(2,max-content);
    justify-content:center;
    align-items:start;
    gap:.9rem 2.3rem;
  }
}

/* ------------------------------------------------------------------------- *
 * Part twenty-four. The service hero paintings are cropped taller on desktop.
 *
 * Added 8 September 2026. TRIAL, review before keeping.
 *
 * The paintings are 16:9 and the hero copy is not. Measured at 1440px the copy
 * column runs 438px on contact to 689px on trauma, against a 282px image, so
 * the painting reads as a small tile beside a tall block of text.
 *
 * No single ratio fixes it. Matching the copy would need 1.15 on contact and
 * 0.73 on trauma, and the copy length is not going to be equalised. 4:3 is a
 * compromise: it takes the image from 282px to about 379px, which halves the
 * imbalance without making the picture the loudest thing on the page.
 *
 * Cropped in CSS rather than regenerated. object-fit does the work, the source
 * files are untouched, and it is one line to revert. Desktop only, so phones
 * still get the whole 16:9 painting, which is the right way round: the wide
 * composition reads best when it is full width.
 *
 * The risk is compositional. A centred 4:3 crop keeps 74% of the width, and
 * these were briefed as wide scenes with generous empty space, so most survive
 * it. Any painting the crop spoils should get a real 4:3 version cut from its
 * PNG in 05 - Image Briefs/generated with a chosen focal point, rather than
 * this rule being widened or abandoned.
 *
 * Not applied to .portrait. Amy's photograph is already the right shape and
 * carries the deckle mask and the washes.
 * ------------------------------------------------------------------------- */
@media (min-width:768px){
  #et-boc .hero-sec .drift img{
    aspect-ratio:4 / 3;
    object-fit:cover;
    object-position:center;
    width:100%;
    height:auto;
  }
}

/* ------------------------------------------------------------------------- *
 * Part twenty-five. The 404 painting.
 *
 * Added 8 September 2026. wc-20, the sun hat bowling along the promenade,
 * sits between the reassuring paragraph and the four routes back into the
 * site. It is in the Theme Builder body layout for the 404, not a page.
 *
 * The figure is capped rather than full width. At the full 1180px measure a
 * 16:9 painting dominates a page whose job is to be calm and get out of the
 * way, and the eye should land on the routes underneath it.
 * ------------------------------------------------------------------------- */
.ahc-404-fig{max-width:620px;}
.ahc-404-fig img{width:100%;height:auto;display:block;}

/* ------------------------------------------------------------------------- *
 * Part twenty-six. Rules that were written but never reached the page.
 *
 * Added 8 September 2026, after diffing every CSS selector in the 26 mock-ups
 * against this file. 336 selectors in the source, 36 with no counterpart here.
 *
 * Two distinct faults, grouped because they are indistinguishable from the
 * front end. Some rules were never ported. Others were ported correctly and
 * then lost the cascade, because Divi prefixes its own rules with #et-boc,
 * an ID selector, which a class-only rule cannot outrank however long the
 * class chain is.
 *
 * Part fourteen, the trust strip, was the first rule written after that was
 * understood. It is also the only list rule in this file that works. Every
 * list rule written before it is doubled: our ::before marker paints, and the
 * native marker Divi restores paints too, so every prose list on the site has
 * carried two bullets per line. Alex spotted it on a blog post; it is on the
 * legal pages, the footer and the breadcrumbs as well.
 *
 * Restated in the same paired form part fourteen uses, so each rule stands
 * whether or not the markup sits inside the builder wrapper.
 * ------------------------------------------------------------------------- */

/* 1. The double bullets. list-style:none, restated so that it wins. */
#et-boc ul.plain,#et-boc ul.ticks,#et-boc .prose ul,#et-boc .policy ul,#et-boc .ft ul,
ul.plain,ul.ticks,.prose ul,.policy ul,.ft ul{list-style:none;}
#et-boc .crumbs ol,.crumbs ol{list-style:none;}
#et-boc .prose ul li,#et-boc .policy ul li,#et-boc ul.plain li,#et-boc .ft li,
.prose ul li,.policy ul li,ul.plain li,.ft li{list-style:none;}

/* 2. ul.ticks. Never ported at all, and used on seven pages: the home page,
 *    about, counselling and four service pages. The sage tick discs were
 *    absent and the lists fell back to Divi's own bullets with no indent. */
#et-boc ul.ticks li,ul.ticks li{padding-left:2.1rem;position:relative;margin-bottom:.7rem;}
#et-boc ul.ticks li::before,ul.ticks li::before{content:"";position:absolute;left:0;top:.34em;
  width:19px;height:19px;border-radius:50%;background:var(--gcid-secondary-color);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1.6 6.2 4.4 9 10.4 3' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/13px no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1.6 6.2 4.4 9 10.4 3' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/13px no-repeat;}

/* 3. The sticky contents sidebar. .artgrid .side was never ported, on nine
 *    pages.
 *
 *    One declaration here is not in the source, and it is the one that makes
 *    the difference. The mock-up lays .artgrid out as CSS grid with
 *    align-items:start, so the aside is already the height of its content and
 *    sticky has room to travel. The build renders the same row as a Divi flex
 *    row, and .side is the 1/3 column itself, which Divi stretches to the full
 *    height of the row. A stretched element has nowhere to stick to, so
 *    position:sticky alone would have looked like a rule that does nothing.
 *    align-self:flex-start restores the source's intent. */
#et-boc .artgrid .side,.artgrid .side{position:sticky;top:112px;align-self:flex-start;}

/* 4. The contents panel's own typography, which lost the cascade the same way
 *    the buttons did in part sixteen: the h2 was taking the global Fraunces
 *    heading and the links were taking the default link colour. */
#et-boc .toc h2{font-size:1.05rem;
  font-family:'Inter Self-Hosted',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-weight:600;color:var(--gcid-heading-color);letter-spacing:.06em;
  text-transform:uppercase;margin:0 0 .8rem;}
#et-boc .toc a{color:var(--gcid-body-color);text-decoration:none;
  border-left:2px solid transparent;}
#et-boc .toc a:hover{color:var(--gcid-heading-color);
  border-left-color:var(--gcid-ahc-sage-mid);}
#et-boc .toc a.active{color:var(--gcid-heading-color);
  border-left-color:var(--gcid-primary-color);font-weight:500;}

/* 5. blockquote. Never ported. One page uses it. */
#et-boc blockquote,blockquote{font-family:'Fraunces Self-Hosted','Fraunces',Georgia,serif;
  font-size:clamp(1.2rem,2.4vw,1.62rem);line-height:1.42;max-width:36ch;}

@media (max-width:900px){
  /* The source releases the sticky aside at the same breakpoint the two-column
     grid collapses, so the contents panel scrolls with the article. */
  #et-boc .artgrid .side,.artgrid .side{position:static;}
}

/* ------------------------------------------------------------------------- *
 * Part twenty-seven. The blog cards, which two rules never reached.
 *
 * Added 8 September 2026. Alex asked why the cards had no padding.
 *
 * The mock-up builds a card as .post > .thumb plus .post > .body. The build
 * makes each card a Divi column carrying .post with a single Blurb module
 * inside it, and Blurb emits its own wrappers:
 *
 *   .post > .et_pb_blurb > .et_pb_blurb_content
 *            > .et_pb_main_blurb_image > span > picture > img
 *            > .et_pb_blurb_container > h3 + .et_pb_blurb_description
 *
 * So .thumb and .body do not exist anywhere on the site, and the two rules
 * that target them have never matched a single element. Measured before
 * writing this: container padding 0px, image mask NONE, image wrapper
 * background transparent, .more margin-top 0px. All four are the mock-up's
 * intent arriving nowhere.
 *
 * Re-pointed at Blurb's own wrappers rather than rebuilding 23 pages. The
 * class names below were read off the rendered page, not recalled.
 * ------------------------------------------------------------------------- */

/* 1. The padding. .post .body in the source. */
#et-boc .post .et_pb_blurb_container{padding:1.4rem 1.5rem 1.6rem;}

/* 2. The linen backing behind the crop. .post .thumb in the source. */
#et-boc .post .et_pb_main_blurb_image{background:var(--gcid-ahc-linen);}

/* 3. The deckle edge. The source lists .post .thumb img alongside the other
 *    masked images; this is the same treatment on the wrapper Blurb builds.
 *    Imagify wraps the img in <picture>, so the mask stays on the img. */
#et-boc .post .et_pb_main_blurb_image img{
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M1 2 C24 0.4 50 2.2 74 1 C86 0.4 96 1.8 99 1.2 L99.2 98.6 C76 99.8 50 98 26 99.2 C14 99.8 4 98.4 1 99 Z' fill='%23000'/%3E%3C/svg%3E") center/100% 100% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M1 2 C24 0.4 50 2.2 74 1 C86 0.4 96 1.8 99 1.2 L99.2 98.6 C76 99.8 50 98 26 99.2 C14 99.8 4 98.4 1 99 Z' fill='%23000'/%3E%3C/svg%3E") center/100% 100% no-repeat;}

/* 4. "Read this" sits on the bottom edge of every card, so a row of cards
 *    with different excerpt lengths still lines its links up. The source does
 *    this with .post .body{flex:1} and .post .more{margin-top:auto}. Blurb
 *    nests four wrappers between the column and the text, so each one has to
 *    pass the height down or margin-top:auto has nothing to push against. */
#et-boc .post,
#et-boc .post .et_pb_blurb,
#et-boc .post .et_pb_blurb_content,
#et-boc .post .et_pb_blurb_container,
#et-boc .post .et_pb_blurb_description{display:flex;flex-direction:column;}
#et-boc .post .et_pb_blurb,
#et-boc .post .et_pb_blurb_content,
#et-boc .post .et_pb_blurb_container,
#et-boc .post .et_pb_blurb_description{flex:1 1 auto;}
#et-boc .post .et_pb_blurb_description > p:last-child{margin-top:auto;margin-bottom:0;}

/* ------------------------------------------------------------------------- *
 * Part twenty-eight. A class-name collision with WordPress.
 *
 * Added 8 September 2026, found while checking that part twenty-six's sticky
 * sidebar actually travelled. It did not, and the reason was not the sticky.
 *
 * Our blog card class is .post. WordPress puts its own class .post on the
 * <article> wrapper of every single post, via post_class(). The two collide,
 * so on every post the article itself has been rendering as a giant blog
 * card: cream background, 10px radius, sage border, a hover lift, and
 * overflow:hidden. Measured, not inferred.
 *
 * overflow:hidden on an ancestor is what breaks position:sticky, because the
 * sticky element is then confined to a box that is not scrollable. So the
 * collision was hiding behind a symptom that pointed somewhere else entirely.
 *
 * This resets the article back to plain. The real fix is to stop calling the
 * card .post, and that is queued with the dynamic loop rebuild, where the
 * cards get rebuilt anyway and can take a class WordPress does not own.
 * Until then this reset is what stands between the collision and the page.
 * ------------------------------------------------------------------------- */
#et-boc article.post,article.post{background:none;border:0;border-radius:0;
  overflow:visible;display:block;box-shadow:none;transition:none;}
#et-boc article.post:hover,article.post:hover{transform:none;box-shadow:none;
  border-color:transparent;}
#et-boc article.post > p:last-child,article.post > p:last-child{margin-bottom:1.15rem;}

/* ------------------------------------------------------------------------- *
 * Part twenty-nine. The dynamic blog feed.
 *
 * Added 8 September 2026. The blog index was seven hand-written Blurb cards,
 * so a post Amy published appeared at its own URL and in the sitemap but not
 * on the blog page until somebody edited that page. It is now two Divi blog
 * modules, one per category, and it maintains itself.
 *
 * Divi's blog module brings its own markup, so the card design is rebuilt on
 * those wrappers rather than on the mock-up's .post > .thumb + .body:
 *
 *   .postfeed > article.et_pb_post
 *       > .et_pb_image_container > a > picture > img
 *       > h3.entry-title  (corrected from h2 in functions.php)
 *       > p.post-meta     (replaced with the designed line in functions.php)
 *       > .post-content > .post-content-inner
 *
 * Specificity note. Part twenty-eight resets article.post back to plain, to
 * undo the collision with WordPress's own .post class on single posts. These
 * cards are also article.post, so every rule here is written under
 * #et-boc .postfeed to outrank that reset rather than fight it.
 * ------------------------------------------------------------------------- */
/* Divi already grids the cards at .et_pb_blog_posts.et_grid_module, so the
 * columns go there. Gridding .postfeed instead nests one grid inside
 * another and squeezes every card to 93px. */
#et-boc .postfeed .et_pb_blog_posts{display:grid;grid-template-columns:repeat(3,1fr);gap:1.5rem;}
#et-boc .postfeed article.et_pb_post{
  background:var(--gcid-ahc-cream);border-radius:10px;overflow:hidden;
  border:1px solid var(--gcid-ahc-border-hairline);
  display:flex;flex-direction:column;margin:0;padding:0;
  transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease;}
#et-boc .postfeed article.et_pb_post:hover{transform:translateY(-3px);
  box-shadow:0 10px 26px var(--gcid-ahc-drop-shadow);
  border-color:var(--gcid-ahc-sage-mid);}

/* The crop. Linen behind it, and the same torn edge as every other image. */
#et-boc .postfeed .et_pb_image_container{margin:0;background:var(--gcid-ahc-linen);}
#et-boc .postfeed .et_pb_image_container img{display:block;width:100%;height:auto;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M1 2 C24 0.4 50 2.2 74 1 C86 0.4 96 1.8 99 1.2 L99.2 98.6 C76 99.8 50 98 26 99.2 C14 99.8 4 98.4 1 99 Z' fill='%23000'/%3E%3C/svg%3E") center/100% 100% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M1 2 C24 0.4 50 2.2 74 1 C86 0.4 96 1.8 99 1.2 L99.2 98.6 C76 99.8 50 98 26 99.2 C14 99.8 4 98.4 1 99 Z' fill='%23000'/%3E%3C/svg%3E") center/100% 100% no-repeat;}

/* The body. Padding is the rule that was missing from the old cards. */
#et-boc .postfeed h3.entry-title{font-size:1.14rem;margin:0;padding:1.4rem 1.5rem 0;}
#et-boc .postfeed h3.entry-title a{color:var(--gcid-heading-color);text-decoration:none;}
#et-boc .postfeed .post-content{padding:0 1.5rem 1rem;display:flex;
  flex-direction:column;flex:1 1 auto;}
#et-boc .postfeed .post-content-inner{font-size:.97rem;margin-bottom:1rem;}
#et-boc .postfeed p.post-meta{padding:.5rem 1.5rem 0;margin:0;font-size:.9rem;
  color:var(--gcid-ahc-ink-muted);}
/* 'Read this' is injected in functions.php, because Divi's blog module has
 * no read-more of its own. It is aria-hidden and not focusable: it points at
 * the same URL as the headline, so exposing it would put two links and two
 * tab stops on every card again. margin-top:auto pins it to the bottom edge
 * so a row of cards with different excerpt lengths still lines its links up. */
#et-boc .postfeed p.more{margin:0 0 0;padding:0 1.5rem 1.6rem;margin-top:auto;
  font-size:.95rem;font-weight:500;}
#et-boc .postfeed p.more a{color:var(--gcid-heading-color);text-decoration:none;
  background-image:linear-gradient(var(--gcid-heading-color),var(--gcid-heading-color));
  background-repeat:no-repeat;background-size:100% 1px;background-position:0 95%;}

@media (max-width:900px){
  #et-boc .postfeed .et_pb_blog_posts{grid-template-columns:repeat(2,1fr);}
}
@media (max-width:767.98px){
  #et-boc .postfeed .et_pb_blog_posts{grid-template-columns:1fr;}
}

/* ------------------------------------------------------------------------- *
 * Part thirty. Pausing the marquee.
 *
 * Added 8 September 2026, from the WCAG 2.2 AA pass.
 *
 * The marquee runs on all seven blog posts. It is moving content that starts
 * automatically and lasts more than five seconds, which engages 2.2.2 Pause,
 * Stop, Hide, a Level A criterion. Part twenty-one already stops it under
 * prefers-reduced-motion, which covers the people most affected, but that is
 * an operating system preference rather than a control on the page.
 *
 * This pauses it whenever a reader hovers it or moves keyboard focus into
 * it, so anyone actually trying to read the line can hold it still. It is
 * animation-play-state only: no layout shift, no visual difference at rest,
 * and the loop resumes from where it stopped rather than jumping.
 *
 * Stated plainly, because it will be asked at audit: this is a mitigation,
 * not full satisfaction of 2.2.2, which wants a mechanism available to every
 * user by any input. A visible pause button would satisfy it outright and was
 * declined on 8 September 2026 as too much furniture for a calm page. The
 * position belongs in the accessibility statement rather than in a comment.
 *
 * focus-within is included although the track holds no focusable content
 * today, so that the behaviour still holds if a link is ever put inside it.
 * ------------------------------------------------------------------------- */
#et-boc .marquee:hover .track,
#et-boc .marquee:focus-within .track,
.marquee:hover .track,
.marquee:focus-within .track{animation-play-state:paused;}


/* -------------------------------------------------------------------------
 * PART 32. Draft and approval markers. .disclose, .confirm, .inject
 * Added 8 September 2026, v1.38.0.
 *
 * Why this is here, written plainly because it is the worst fault found in
 * this build. These three classes mark content that is NOT approved for
 * publication: a line drafted in Amy's own voice, a question waiting on her
 * answer, and a placeholder where a plugin will inject content at build time.
 * The markup was ported from the mock-ups. The CSS was not. Thirteen blocks
 * across nine pages were therefore rendering as ordinary body copy, with the
 * "Draft, for Amy to approve" tag showing as plain 17px grey text.
 *
 * The .disclose block carries Amy's ADHD diagnosis. The standing rule on this
 * account is that it does not publish without her explicit yes. Invisible
 * marking is the failure mode that rule exists to prevent.
 *
 * These rules were on the missing-selector list produced by the stylesheet
 * diff and were dismissed as mock-up furniture. They were not furniture.
 * Nothing on that list is dismissed again without opening the markup.
 *
 * Token mapping from the mock-up variables:
 *   --card    -> --gcid-ahc-cream        --linen  -> --gcid-ahc-linen
 *   --rose-d  -> --gcid-ahc-rose-deep    --sage-d -> --gcid-secondary-color
 *   --terra-b -> --gcid-primary-color    --terra-d -> --gcid-heading-color
 *   --disp    -> the self-hosted Fraunces stack used elsewhere here
 *
 * Tag contrast measured against white, all three pass WCAG 1.4.3 AA:
 *   rose-deep #9C4141 6.47:1, primary #A9593C 5.02:1, secondary #5D7E5F 4.55:1
 *
 * #et-boc prefix per the cascade rule in part 22: Divi's own rules are ID
 * scoped and a class-only selector cannot outrank them. The bare selector is
 * restated after it so the block still marks itself outside the Divi wrapper.
 * ------------------------------------------------------------------------- */

/* Disclosure. A line in Amy's voice, drafted by us, awaiting her approval. */
#et-boc .disclose,
.disclose{background:var(--gcid-ahc-cream);border:1.5px dashed var(--gcid-ahc-rose-deep);
  border-radius:10px;padding:1.6rem 1.7rem;margin:1.6rem 0;}
#et-boc .disclose .tag,
.disclose .tag{display:inline-block;background:var(--gcid-ahc-rose-deep);color:#fff;
  font-size:.7rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  padding:.3rem .7rem;border-radius:3px;margin-bottom:.9rem;}
#et-boc .disclose p,
.disclose p{font-family:'Fraunces Self-Hosted','Fraunces',Georgia,serif;font-size:1.22rem;
  line-height:1.45;color:var(--gcid-heading-color);}
#et-boc .band-card .disclose,
.band-card .disclose{background:var(--gcid-ahc-linen);}

/* Confirm. A question for Amy. Same shape, quieter colour and type size. */
#et-boc .confirm,
.confirm{background:var(--gcid-ahc-cream);border:1.5px dashed var(--gcid-secondary-color);
  border-radius:10px;padding:1.35rem 1.5rem;margin:1.3rem 0;}
#et-boc .confirm .tag,
.confirm .tag{display:inline-block;background:var(--gcid-secondary-color);color:#fff;
  font-size:.7rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  padding:.3rem .7rem;border-radius:3px;margin-bottom:.8rem;}
#et-boc .confirm p,
.confirm p{font-size:1rem;}
#et-boc .band-card .confirm,
.band-card .confirm{background:var(--gcid-ahc-linen);}

/* Inject. A placeholder shown as what it is, not disguised as copy. */
#et-boc .inject,
.inject{background:var(--gcid-ahc-cream);border:1.5px dashed var(--gcid-primary-color);
  border-radius:10px;padding:1.4rem 1.5rem;margin:1.4rem 0;}
#et-boc .inject code,
.inject code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.94rem;
  background:var(--gcid-ahc-linen);color:var(--gcid-heading-color);padding:.25rem .5rem;
  border-radius:4px;display:inline-block;word-break:break-all;}
#et-boc .inject .tag,
.inject .tag{display:inline-block;background:var(--gcid-primary-color);color:#fff;
  font-size:.7rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  padding:.3rem .7rem;border-radius:3px;margin-bottom:.8rem;}
#et-boc .inject p,
.inject p{font-size:1rem;}
#et-boc .band-card .inject,
.band-card .inject{background:var(--gcid-ahc-linen);}


/* -------------------------------------------------------------------------
 * PART 33. Testimonials. .voices and .voice
 * Added 9 September 2026, v1.39.0.
 *
 * Why this exists. The mock-ups never designed a testimonial module, and the
 * live site carries ten testimonials that the new build had none of. This is
 * the module, built from parts the site already uses rather than invented.
 *
 * THE DESIGN DECISION, and it is an accessibility one as much as a visual one.
 * The obvious testimonial treatment is a large decorative quote glyph and a
 * carousel. Both were rejected:
 *
 *   A CSS-generated quote mark sits in `content`, and several screen readers
 *   announce generated content. A pseudo-element cannot carry aria-hidden, so
 *   the mark cannot be reliably hidden from a screen reader once it is drawn
 *   that way. The site already has a better motif: the hand-painted left rule
 *   used on .capsule, .tldr and .boundary. The same brush mask is reused here,
 *   verbatim from that rule rather than retyped, so the stroke is identical.
 *
 *   A carousel would engage WCAG 2.2.2 Pause Stop Hide if it auto-advanced,
 *   2.5.7 Dragging Movements if it swiped, and it hides most of the content
 *   from most readers. These are static, stacked and always visible.
 *
 * Contrast measured against the two grounds this sits on, both pass 1.4.3 AA:
 *   heading-color #8F4B33 on cream 5.97:1, on linen 5.06:1
 *   ink-muted    #5B4C40 on cream 7.53:1, on linen 6.38:1
 *
 * Semantics live in the markup, not here: blockquote wrapping p, with the
 * attribution in a footer. Not cite, which is for the title of a work rather
 * than the name of a person.
 * ------------------------------------------------------------------------- */

#et-boc .voices .voicegrid,
.voices .voicegrid{display:grid;grid-template-columns:1fr;gap:1.5rem;margin-top:0;}
#et-boc .voices .voicegrid.two,
.voices .voicegrid.two{grid-template-columns:repeat(2,1fr);}

#et-boc .voice,
.voice{position:relative;border-left:0;background:var(--gcid-ahc-cream);border-radius:10px;
  padding:1.7rem 1.8rem 1.5rem;margin:0;}
#et-boc .band-card .voice,
.band-card .voice{background:var(--gcid-ahc-linen);}

/* The painted left edge, identical to .capsule and .tldr. */
#et-boc .voice::before,
.voice::before{content:"";position:absolute;left:0;top:0;bottom:0;width:6px;
  background:var(--gcid-ahc-rose-deep);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 100' preserveAspectRatio='none'%3E%3Cpath d='M1.6 0 C4.6 12 1.2 26 3.4 40 C5.4 54 1.4 66 3.2 80 C4.6 90 2.2 95 3 100 L6 100 L6 0 Z' fill='%23000'/%3E%3C/svg%3E") left/100% 100% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 100' preserveAspectRatio='none'%3E%3Cpath d='M1.6 0 C4.6 12 1.2 26 3.4 40 C5.4 54 1.4 66 3.2 80 C4.6 90 2.2 95 3 100 L6 100 L6 0 Z' fill='%23000'/%3E%3C/svg%3E") left/100% 100% no-repeat;}

#et-boc .voice p,
.voice p{font-family:'Fraunces Self-Hosted','Fraunces',Georgia,serif;
  font-size:clamp(1.06rem,1.9vw,1.3rem);line-height:1.5;color:var(--gcid-heading-color);
  margin:0 0 1rem;max-width:52ch;}
#et-boc .voice p:last-of-type,
.voice p:last-of-type{margin-bottom:1rem;}

#et-boc .voice .voice-by,
.voice .voice-by{font-family:'Inter Self-Hosted',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:.78rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;
  color:var(--gcid-ahc-ink-muted);margin:0;}

/* The site footer is styled on the bare `footer` element selector, so a footer
   inside a blockquote inherited a cream ground, a top border and 136px of
   padding. Found on 9 September 2026 by measuring the rendered attribution,
   which is the only way it shows: the markup is correct and the collision is
   entirely in the cascade. Same shape as `.post` colliding with post_class().
   The attribution keeps the right semantics and this undoes the collision. */
#et-boc .voice footer,
.voice footer{background:none;padding:0;border-top:0;position:static;z-index:auto;
  font-size:inherit;}

/* An editorial cut inside a quotation is shown, never silent. */
#et-boc .voice .cut,
.voice .cut{color:var(--gcid-ahc-ink-muted);}

@media (max-width:820px){
  #et-boc .voices .voicegrid.two,
  .voices .voicegrid.two{grid-template-columns:1fr;}
}


/* -------------------------------------------------------------------------
 * PART 34. FAQ accordions, the lone testimonial, and the painted left edge.
 * Added 9 September 2026, v1.40.0.
 * ------------------------------------------------------------------------- */

/* A. FAQ ACCORDIONS.
 *
 * 44 of them across 8 pages, and every one was rendering in Divi's factory
 * styling: a #f4f4f4 box, a #d9d9d9 hairline, square corners, a #666 title and
 * a pale grey plus sign in the ETmodules icon font. The mock-up designed these
 * as "details.faq" and its own comment says "Divi 5: Accordion module", so the
 * intent was always to style Divi's toggle. It was never done.
 *
 * The chevron is rebuilt from two borders, exactly as the mock-up draws it,
 * because Divi's icon is a glyph in an icon font and the site has no other
 * icon-font furniture anywhere. */

#et-boc .et_pb_toggle,
.et_pb_toggle{background:var(--gcid-ahc-cream);border:1px solid var(--gcid-ahc-border-hairline);
  border-radius:9px;margin-bottom:.85rem;padding:0;box-shadow:none;
  transition:border-color .22s ease;}
#et-boc .band-card .et_pb_toggle,
.band-card .et_pb_toggle{background:var(--gcid-ahc-white);}
#et-boc .et_pb_toggle:hover,
.et_pb_toggle:hover{border-color:var(--gcid-ahc-sage-mid);}

#et-boc .et_pb_toggle .et_pb_toggle_title,
.et_pb_toggle .et_pb_toggle_title{cursor:pointer;margin:0;position:relative;
  padding:1.15rem 3.4rem 1.15rem 1.4rem;
  font-family:'Fraunces Self-Hosted','Fraunces',Georgia,serif;font-size:1.1rem;
  line-height:1.35;color:var(--gcid-heading-color);}

/* Divi paints a plus sign from an icon font. Replaced with the mock-up chevron. */
#et-boc .et_pb_toggle .et_pb_toggle_title::before,
.et_pb_toggle .et_pb_toggle_title::before{content:"";display:block;
  width:11px;height:11px;background:none;border-radius:0;
  border-right:2.2px solid var(--gcid-secondary-color);
  border-bottom:2.2px solid var(--gcid-secondary-color);
  border-top:0;border-left:0;
  position:absolute;right:1.5rem;top:50%;left:auto;
  transform:translateY(-70%) rotate(45deg);transition:transform .22s ease;
  font-family:inherit;font-size:0;color:transparent;}
#et-boc .et_pb_toggle_open .et_pb_toggle_title::before,
.et_pb_toggle_open .et_pb_toggle_title::before{transform:translateY(-25%) rotate(-135deg);}

#et-boc .et_pb_toggle .et_pb_toggle_content,
.et_pb_toggle .et_pb_toggle_content{padding:0 1.4rem 1.3rem;}
#et-boc .et_pb_toggle .et_pb_toggle_content p,
.et_pb_toggle .et_pb_toggle_content p{font-size:1rem;}

/* The title is made focusable in functions.php, so focus has to be visible.
   Divi's toggle is a div and a heading, with no focus style of its own. */
#et-boc .et_pb_toggle .et_pb_toggle_title:focus-visible,
.et_pb_toggle .et_pb_toggle_title:focus-visible{outline:2.4px solid var(--gcid-primary-color);
  outline-offset:-3px;border-radius:9px;}

@media (prefers-reduced-motion:reduce){
  #et-boc .et_pb_toggle,
  .et_pb_toggle,
  #et-boc .et_pb_toggle .et_pb_toggle_title::before,
  .et_pb_toggle .et_pb_toggle_title::before{transition:none;}
}

/* B. ONE TESTIMONIAL ON ITS OWN.
 *
 * "blockquote" is capped at 36ch site-wide, which is right for a pull-quote and
 * wrong for a card: a single card sat 601px wide in a 1180px grid with dead
 * space beside it. A .voice sets its own measure on the paragraph instead.
 *
 * And a lone card in a grid built for two looks like a mistake, so on its own a
 * testimonial becomes the pull-quote the site already uses. Two or more stay
 * as cards. */

#et-boc .voice,
.voice{max-width:none;}

#et-boc .voicegrid.solo .voice,
.voicegrid.solo .voice{background:none;border-radius:0;padding:.2rem 0 .2rem 1.8rem;}
#et-boc .band-card .voicegrid.solo .voice,
.band-card .voicegrid.solo .voice{background:none;}
#et-boc .voicegrid.solo .voice p,
.voicegrid.solo .voice p{font-size:clamp(1.22rem,2.3vw,1.68rem);max-width:44ch;}

/* C. THE PAINTED LEFT EDGE.
 *
 * The brush stroke is drawn inside a 6px strip at the module's left edge, and
 * the stroke does not fill that strip, so the module's own pale background was
 * visible as a sliver beside the paint.
 *
 * The fix is to stop the module's background reaching that strip at all: a
 * transparent 6px left border with the background clipped to the padding box.
 * The strip then shows the band behind, so the paint reads as the module's
 * edge rather than as a line drawn just inside it.
 *
 * The stroke has to move with it. An absolutely positioned pseudo-element is
 * placed against the padding box, not the border box, so "left:0" would now sit
 * after the border. "left:-6px" puts it back in the strip. */

#et-boc .capsule,#et-boc .tldr,#et-boc .boundary,#et-boc .voice,
.capsule,.tldr,.boundary,.voice{border-left:6px solid transparent;
  background-clip:padding-box;}

#et-boc .capsule::before,#et-boc .tldr::before,#et-boc .boundary::before,#et-boc .voice::before,
.capsule::before,.tldr::before,.boundary::before,.voice::before{left:-6px;}


/* -------------------------------------------------------------------------
 * PART 35. Rejoining a panel that the build split in two.
 * Added 9 September 2026, v1.41.0.
 *
 * The mock-ups nest the content inside the card:
 *
 *   <section class="band-sage"><div class="wrap"><div class="panel">
 *     <div class="sec-head"><h2>How the sessions themselves work.</h2></div>
 *     <div class="g2"> ...the actual content... </div>
 *   </div></div></section>
 *
 * A Divi row cannot contain another row, so the build made them two sibling
 * rows. The panel then held nothing but a heading, and the content it was
 * supposed to contain sat outside the card on the bare sage band.
 *
 * Two visible faults from one structural mistake: a cream card standing empty
 * under its own heading, and body copy on a mid-green ground it was never
 * designed to sit on. Four sections across four pages, every one on band-sage.
 *
 * Found on 9 September 2026 from a screenshot. Both halves are given the panel
 * treatment and the seam between them is closed, so the pair reads as the one
 * card the design intended. The classes are explicit rather than an adjacency
 * selector, because a complete panel followed by an unrelated row is a normal
 * arrangement elsewhere and must not be joined to it.
 * ------------------------------------------------------------------------- */

#et-boc .panel-top,
.panel-top{border-bottom-left-radius:0;border-bottom-right-radius:0;
  padding-bottom:0;margin-bottom:0;}

#et-boc .panel-btm,
.panel-btm{border-top-left-radius:0;border-top-right-radius:0;
  padding-top:0;margin-top:0;}

/* Divi puts its own margin on a row. Both halves of the seam have to lose it,
   or the card shows a cream gap with a band-coloured line through it. */
#et-boc .et_pb_row.panel-top,
.et_pb_row.panel-top{margin-bottom:0;}
#et-boc .et_pb_row.panel-btm,
.et_pb_row.panel-btm{margin-top:0;}

/* Two of the four had their content split across two rows as well, so the
   middle of the card loses its radius and every vertical edge. */
#et-boc .panel-mid,
.panel-mid{border-radius:0;padding-top:0;padding-bottom:0;}
#et-boc .et_pb_row.panel-mid,
.et_pb_row.panel-mid{margin-top:0;margin-bottom:0;}

/* The section is a flex container with a 60px gap, which is what actually
   separated the two halves. Row margins were already zero, so closing the seam
   means closing the gap on the section itself. Safe here because every row in
   these four sections belongs to the panel; that was checked before writing. */
#et-boc .panel-joined,
.panel-joined{gap:0;}

/* Divi's column carries its own vertical padding, which would double up at the
   seam once the gap is gone. */
#et-boc .panel-mid > .et_pb_column,
.panel-mid > .et_pb_column,
#et-boc .panel-btm > .et_pb_column,
.panel-btm > .et_pb_column{padding-top:0;}

/* Stress and burnout puts a zebra list inside the panel. The alternation was
   cream against the bare sage band; inside a cream card that reads as nothing
   at all. Linen on cream is the same move the stylesheet already makes for a
   zebra list sitting on a cream band. */
#et-boc .zebra-row.panel.zebra-odd,
.zebra-row.panel.zebra-odd{background:var(--gcid-ahc-linen);}
#et-boc .zebra-row.panel.zebra-even,
.zebra-row.panel.zebra-even{background:var(--gcid-ahc-cream);}

/* .zebra-row sets its own 6px radius, which would round the card's bottom
   corners to the wrong value. The seam classes own the card's corners. */
#et-boc .panel-btm.zebra-row,
.panel-btm.zebra-row{border-bottom-left-radius:12px;border-bottom-right-radius:12px;}

/* The heading keeps its own spacing, which is what separates it from the
   content now that the panel's bottom padding is gone. */
#et-boc .panel-top .sec-head,
.panel-top .sec-head{margin-bottom:0;}
#et-boc .panel-top > h2,
.panel-top > h2{margin-bottom:0;}


/* ============================================================================
 * PART 36. A zebra row's vertical padding is its own, not the panel's.
 * Added 9 September 2026, v1.42.0.
 *
 * Part 35 closed the seam inside a split panel by zeroing padding on
 * .panel-top, .panel-mid and .panel-btm. That is correct when the row IS the
 * panel, because the padding being removed is the panel's own 2.2rem and the
 * seam has to disappear.
 *
 * It is wrong when the row is ALSO a .zebra-row. There the vertical padding is
 * the list item's, set at 1.5rem in part 4, and it is what gives each band its
 * breathing room. Removing it collapses every band onto its own text.
 *
 * Measured on 9 September 2026, before the fix:
 *
 *   /anxiety-counselling/            zebra rows outside a panel, the reference
 *                                    24px above and below the text in every row
 *   /stress-and-burnout-counselling/ 0px above, 0px below, and 0px between the
 *                                    text of one band and the next
 *   /creative-counselling/           same shape, 5 banded rows
 *   /wellbeing-services-organisations/ same shape, 5 banded rows
 *
 * Three pages, fifteen bands, and the text of adjacent bands literally
 * touching. Shipped with part 35 and live on two pages since; found from a
 * screenshot on 9 September once a third page was built on the same component.
 * Neither a build log nor a source read had caught it, which is the same
 * lesson as the .voice footer collision: measure the rendered geometry.
 *
 * The three pages that use the seam classes on non-zebra rows, /contact/,
 * /neurodivergent-affirming-supervision/ and /neurodivergent-affirming-therapy/,
 * are untouched by this and must stay that way. That is why the selectors name
 * .zebra-row rather than relaxing part 35.
 * ========================================================================= */

#et-boc .zebra-row.panel-top,
.zebra-row.panel-top,
#et-boc .zebra-row.panel-mid,
.zebra-row.panel-mid,
#et-boc .zebra-row.panel-btm,
.zebra-row.panel-btm{padding-top:1.5rem;padding-bottom:1.5rem;}


/* ============================================================================
 * PART 37. The header nav gained an eighth item, and it did not fit.
 * Added 9 September 2026, v1.43.0.
 *
 * "Organisations" went into the main nav on 9 September, taking it from seven
 * top-level items plus the booking button to eight. Measured on /about/ as the
 * distance from the nav's right edge to the header container's right edge, so
 * a negative number means the nav has run out of the bar:
 *
 *   width    seven items, current CSS    eight items, current CSS
 *   905px    -56                         -168
 *   960px    -3                          not measured
 *   1000px   +35                         not measured
 *   1024px   +51                         -55
 *   1150px   not measured                -23
 *   1280px   not measured                +22
 *
 * Two faults, and only the second is new:
 *
 * 1. Seven items already overflowed the bar between the 900px mobile
 *    breakpoint and about 965px. That has been live since the build. The
 *    tightening block at 901 to 1150px was not enough at the bottom of its own
 *    range, and nobody had looked at the header at 905px.
 * 2. The eighth item pushed the overflow up to about 1250px, which is most
 *    laptops.
 *
 * Fixed by moving the mobile breakpoint up to 1000px, which is where eight
 * items stop fitting at a readable size, and tightening harder across a wider
 * band. After: mobile to 1000px inclusive, then +31px clearance at 1001px,
 * +51 at 1024, +56 from 1100 to 1300, and +22 above that on the untightened
 * base.
 *
 * The 1000 and 1000 handover is deliberate rather than sloppy. Written as
 * max-width:999px and min-width:1000px it left a one-pixel window at exactly
 * 999 where neither rule applied and the desktop nav rendered untightened at
 * -78. Overlapping the boundary closes it, and display:none wins inside the
 * overlap because the mobile block comes first and the desktop block sets no
 * display.
 *
 * The older 901 to 1150px tightening block is left where it is. Below 1001px
 * the nav is now hidden so it has nothing to act on, and above it this block
 * wins on source order.
 * ========================================================================= */

@media (max-width:1000px){
  nav.main a:not(.btn){display:none;}
  nav.main{display:none;}
  .mobnav{display:block;margin-left:auto;}
  .hd{position:relative;}
}

@media (min-width:1000px) and (max-width:1300px){
  nav.main{gap:.6rem;}
  nav.main a:not(.btn){font-size:.86rem;}
  nav.main .btn{font-size:.85rem;padding-left:.85rem;padding-right:.85rem;}
}


/* ============================================================================
 * PART 38. The trust strip pushed the whole page sideways at tablet width.
 * Added 9 September 2026, v1.44.0.
 *
 * Found on 9 September while checking the nav change had not broken anything.
 * It had not. This is older, and worse.
 *
 * Part 22 gave .trust ul a two-column grid above 768px:
 * grid-template-columns:repeat(2,max-content). max-content never shrinks. Where
 * the labels are long the two columns simply exceed the container and take the
 * page with them. Measured at 768px, admin bar removed, document scrollWidth
 * against clientWidth:
 *
 *   /about/                             106px of horizontal page overflow
 *   /wellbeing-services-organisations/    9px
 *   /creative-counselling/                2px
 *   /stress-and-burnout-counselling/      0px
 *
 * So it depends entirely on how long that page's four labels are, which is why
 * it was never seen: the page anyone would have tested reads clean. On /about/
 * a 768px viewport has been scrolling sideways since the build.
 *
 * minmax(0,max-content) caps each column at the space available and lets a long
 * label wrap instead. Verified afterwards at 768, 820, 900, 1024, 1200 and
 * 1440: two columns, two rows, zero overflow at every one.
 *
 * The second half. Part 22 also top-aligns the icon below 900px, because a
 * label that wraps to two lines leaves a centred icon floating at the midpoint.
 * With the grid capped, wrapping now happens up to about 999px rather than 900.
 * Measured at 901 and 960: one item wraps and its icon sits 16px down instead
 * of 3px. The band is extended to match, which also lines it up with the new
 * 1000px nav breakpoint in part 37.
 * ========================================================================= */

@media (min-width:768px){
  #et-boc .trust ul,
  .trust ul{grid-template-columns:repeat(2,minmax(0,max-content));}
}

@media (min-width:901px) and (max-width:999px){
  #et-boc .trust li,
  .trust li{align-items:flex-start;}
  .trust li svg{margin-top:.2em;}
}


/* ============================================================================
 * PART 39. Every in-page anchor landed underneath the sticky header.
 * Added 9 September 2026, v1.45.0.
 *
 * The site header is position:sticky and about 84px tall. Follow any anchor
 * link and the browser scrolls the target to y=0, which puts the top of it
 * behind the header. Measured on the privacy policy: the target's top sat 42px
 * above the header's bottom edge, so the first two lines were covered.
 *
 * This is not new and it is not confined to the anchors added today. It applies
 * to every in-page link the site already has, including "#fees" from the
 * footer, "#nd" from the burnout hero and "#services" on the organisations
 * page. It was found while checking that a link to a draft marker actually
 * lands where it says it does.
 *
 * scroll-margin-top on the target is the whole fix. It affects nothing except
 * where a scroll comes to rest, so applying it to every element carrying an id
 * inside the builder wrapper is safe and saves having to think about it again
 * each time an anchor is added. 6rem clears the 84px header with a little air.
 * ========================================================================= */

#et-boc [id],
.et-l [id]{scroll-margin-top:6rem;}


/* ============================================================================
   Part thirty, 10 September 2026. The contact page room row, now four cards.
   ============================================================================ */
/* The Lewes room went on the site on 10 September, taking the "Where to find me"
   row from three cards to four. The card is the Divi column itself: the linen
   background and the 27.2px by 25.6px padding sit on .set-swatch > *, so the
   text column inside a card is the column width less 51.2px.

   Four across was tried first and rejected on the look, 13 September 2026: at 1180
   each card's text column is 192px, the cards read as four narrow strips, and
   because Brighton and Hove carry long access notes while Lewes and Online are
   short, the bottoms came out ragged.

   Two by two fixes both. Each card gets about 560px at 1180, and the pairing puts
   the two long cards on one row and the two short ones on the other, so flex
   stretch lines the bottoms up inside each row instead of across all four.

   Below 768, which will not carry "Netwerks Lewes, G06, 4 Fisher Street,
   Lewes BN7 2DG" without breaking it over four lines, so the cards wrap two by
   two through that band. Below 768 part sixteen already stacks every Divi row
   and this row goes with it.

   Divi gutters this row with column-gap:5.5%, a PERCENTAGE, not a fixed 45px. An
   earlier version of this rule assumed 45px, measured at a narrow viewport where
   5.5% happens to be about that. At 1180 the real gap is 64px, so two cards at
   calc(50% - 22.5px) plus the gap exceeded the row and every card wrapped onto its
   own line: half width, stacked, worse than the four-across it replaced. The file
   was correct and the rendered page was not, which is why this needed measuring
   rather than reading. Two to a row is calc((100% - 5.5%) / 2).

   Scoped to .rooms, added to this row alongside .set-swatch, because nine other
   pages use .set-swatch with three cards and must not move. 6.8g30: a class that
   exists only as a hook is invisible unless the markup and the rule name it
   together, so it is named in both. */
@media (min-width:768px){
  #et-boc .et_pb_row.set-swatch.rooms{flex-wrap:wrap;}
  #et-boc .et_pb_row.set-swatch.rooms > .et_pb_column{width:calc((100% - 5.5%) / 2);max-width:calc((100% - 5.5%) / 2);}
}


/* ============================================================================
   Part thirty-one, 10 September 2026. Two reflow faults, both older than the
   Lewes work, both found by measuring and both one line.
   ============================================================================ */
/* 1. The deckle swatch tilt bled past the viewport.

   .set-swatch > *:nth-child(2n) and (3n) rotate the column by half a degree,
   and the column is the card. A rotated box's bounding box is wider than the
   box, by roughly its height times sin(0.5deg). The row is full-bleed at any
   viewport under about 1196px, because it is width:100% with a 1180px cap, so
   the cards sit hard against the viewport edge and the rotation pushed 1 to 2px
   past it. The document then scrolled sideways: enough for a scrollbar, not
   enough to see.

   Measured on all seven pages carrying .set-swatch, at 1440, 1180 and 1024:
   every one of them overflowed by 1 or 2px somewhere, and 8px of horizontal
   padding on the row takes all of them to 0. Part seventeen fixed the same
   mechanism below the mobile breakpoint in June by moving the tilt inward; this
   is the same idea applied at the widths part seventeen did not cover.

   The padding is on the row, so it shrinks the cards rather than moving them,
   and the tilt keeps its room instead of being switched off. */
#et-boc .et_pb_row.set-swatch{padding-left:8px;padding-right:8px;}

/* 2. A fractional dead band at 767px.

   Part sixteen stacked every Divi row under @media (max-width:767px), and part
   thirty wraps the room cards from (min-width:768px). At a measured viewport of
   767 point something, neither matched: rows rendered un-stacked at four cards
   of 157px and the page scrolled sideways by 5px. Confirmed with matchMedia
   inside the frame rather than inferred, because a query that does not match
   looks exactly like a rule losing on specificity.

   All four max-width:767px blocks move to 767.98px together, so the stacking,
   the portrait pseudo-element bleed, the swatch tilt reset and the post-feed
   grid all cross the breakpoint at the same moment. Splitting them would leave
   a band with stacked rows and a live tilt. Behaviour at exactly 768 and above
   is unchanged. Runbook 6.8g28 and 6.8g35. */

/* Trust list, single column below the mobile breakpoint.

   The base rule centres a wrapping flex row, so at narrow widths any item
   alone on its line is centred and the icon column goes ragged. Measured at
   375px the four rows started at 20, 0, 0 and 98px. The grid rule from
   768px up never covered this. Single column, left aligned, with the 20px
   gutter the body copy already uses.

   767.98px to stay with the other max-width blocks. Added 15 September 2026. */
@media (max-width: 767.98px) {
  #et-boc .trust ul,
  .trust ul {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    justify-items: start;
    row-gap: 0.7rem;
    padding: 1.15rem 20px;
  }
}

/* The reading progress bar's section is a utility wrapper.

   The bar itself is position:fixed, so the section around it has nothing to
   show, yet it took Divi's default 50px top and bottom padding and put 101px
   of empty white between the header and the breadcrumb on all seven posts.
   Measured: section 101px to 1px, header-to-breadcrumb gap 102px to 2px, and
   the bar stays fixed at 5px throughout.

   Same treatment as .crumbs and .ld-json above. Added 15 September 2026. */
#et-boc .et_pb_section:has(> .et_pb_row > .et_pb_column > .progress),
.et_pb_section:has(> .et_pb_row > .et_pb_column > .progress){
  padding-top:0;padding-bottom:0;
}
#et-boc .et_pb_section:has(> .et_pb_row > .et_pb_column > .progress) .et_pb_row,
.et_pb_section:has(> .et_pb_row > .et_pb_column > .progress) .et_pb_row{
  padding-top:0;padding-bottom:0;
}

/* Breadcrumb padding loses to Divi on blog posts.

   On a post the breadcrumb ol sits inside #left-area, so Divi's
   `#left-area ol` rule carries an ID and outranks `.crumbs ol`, applying
   `padding: 0 0 23px`. The text then sits hard against the top of the band
   with 23px below it. Pages escape it because they only match
   `.et-l--body ol`, which ties on specificity and loses to the later rule.

   Invisible until 15 September, when zeroing the progress-bar section moved
   the band up against the header. Measured: space above the text 0px to 11px.

   Prefixed with #et-boc to beat the ID, the same way the list-style rule
   above it already is. Added 15 September 2026. */
#et-boc .crumbs ol,
.crumbs ol{ padding:0.85rem 0; }
@media (max-width: 640px){
  #et-boc .crumbs ol,
  .crumbs ol{ padding:0.7rem 0; }
}

/* Mobile gutter. Divi sets no horizontal padding on rows or columns.

   Nothing in stored content carries a spacing attribute, so every section, row
   and column runs Divi's bare defaults, and the default is zero. At 375px that
   left 19 text and button modules sitting hard against both screen edges on the
   home page alone, against a body copy gutter of 20px elsewhere on the same page.

   Measured before and after, home page at 375px: non-code modules flush to an
   edge 19 to 0, code modules unchanged at 4, all 15 coloured bands still full
   width, no horizontal overflow. Removing the block returns it to 19.

   Code modules are exempt by negative margin because every one on this site
   manages its own internal padding: the header, the footer, the trust strip, the
   progress bar, the JSON-LD blocks and the marquee. The Theme Builder header and
   footer sections are excluded outright for the same reason.

   THIS IS A STOPGAP. The right home for it is a default Spacing option group
   preset, which is what Divi 5 is for. Attempted 15 September 2026 and the
   preset would not persist: the page save never fired
   POST /divi/v1/global-data/global-preset/sync and gave no failure signal.
   Delete this block when the preset migration lands. Added 15 September 2026. */
@media (max-width: 767.98px){
  #et-boc .et_pb_section:not([class*="_tb_header"]):not([class*="_tb_footer"]) > .et_pb_row > .et_pb_column{
    padding-left: 20px;
    padding-right: 20px;
  }
  #et-boc .et_pb_section:not([class*="_tb_header"]):not([class*="_tb_footer"]) > .et_pb_row > .et_pb_column > .et_pb_code{
    margin-left: -20px;
    margin-right: -20px;
  }
}

/* -------------------------------------------------------------------------
 * Part forty-two. Nothing overflows sideways, at any width or text size.
 *
 * Added 25 September 2026, after Alex saw the page pan sideways and the Menu
 * button touch the edge on a Galaxy S22. Measured on all 23 URLs and the 404
 * at 240 to 1440px and at 100, 115, 130 and 150 per cent text: the live site
 * overflowed at 128 to 168 of those combinations per page, this part at none.
 *
 * Four faults, one pattern: an item that will not shrink below its content.
 *  1. Header. The row needs 364px (logo 201, gap 24, Menu 99, gutters 40), so
 *     below 344px the Menu button leaves the screen.
 *  2. Footer. The three .ft columns keep min-width:auto and overflow at large
 *     text sizes between 890 and 950px.
 *  3. Privacy policy. The .artgrid min-width:0 rule stopped at 900px, so from
 *     901px the tables hold the text column open and squeeze the side column.
 *  4. Testimonials. The .voicegrid track is held open by long words plus
 *     padding at 240px with large text.
 * A small script in the header layout (html.nav-compact, html.menu-icon)
 * covers what a fixed breakpoint cannot: text size and zoom.
 * ------------------------------------------------------------------------- */

/* 1. Header. The Menu button never shrinks; the logo scales in the mobile
   layout only, so the desktop logo stays at 201px. */
.wrap.hd > .mobnav{ flex:none; }
@media (max-width: 1000px){
  .wrap.hd > .logo{ flex:0 1 auto; min-width:0; }
  .wrap.hd > .logo svg{ display:block; width:100%; max-width:201px; height:auto; }
}
@media (max-width: 400px){
  .wrap.hd{ column-gap:12px; }
  .wrap.hd > .mobnav > summary{ padding-left:.65rem; padding-right:.65rem; }
}

/* Set by the header script when the desktop nav would pass the screen edge. */
html.nav-compact .wrap.hd > .logo{ flex:0 1 auto; min-width:0; }
html.nav-compact .wrap.hd > .logo svg{ display:block; width:100%; max-width:201px; height:auto; }
html.nav-compact nav.main{ display:none; }
html.nav-compact .mobnav{ display:block; margin-left:auto; }
html.nav-compact .hd{ position:relative; }

/* Set by the header script when the logo would fall below 150px. The summary
   keeps aria-label="Menu" and a 44px target. */
html.menu-icon .wrap.hd > .mobnav > summary{ font-size:0; gap:0; min-width:44px; min-height:44px; justify-content:center; }

/* Above 1300px the nav returned to full size and overhung the 1180px column
   by 73px. The compact sizing now applies at every desktop width. */
@media (min-width: 1300px){
  nav.main{ gap:.6rem; }
  nav.main a:not(.btn){ font-size:.86rem; }
  nav.main .btn{ font-size:.85rem; padding-left:.85rem; padding-right:.85rem; }
}

/* 2. Footer columns may shrink below their content. */
.ft > *{ min-width:0; }
.ft a{ overflow-wrap:anywhere; }

/* 3. Two-column rows may shrink at every width, not only up to 900px. Table
   cells wrap long strings such as cookie names instead of widening the column. */
.artgrid > *{ min-width:0; }
@media (min-width: 901px){
  #et-boc td, #et-boc th, main td, main th{ overflow-wrap:anywhere; }
}

/* 4. Testimonial cards may shrink, and long words wrap. */
.voicegrid > *{ min-width:0; }
.voice{ overflow-wrap:break-word; }
