/* CS Personal Training, shared stylesheet.
   Extracted from the homepage on 15 Aug 2026 when the site went multi-page.
   One file, cached hard, so every page after the first costs nothing. */

:root{
  --ink:#0b0b0b;
  --ink-2:#141413;
  --paper:#fff;
  --silver:#9d9d9c;        /* 7.4:1 on --ink, so it is a text colour here */
  --silver-2:#c9c9c6;
  --hair:rgba(255,255,255,.14);
  --hair-dark:rgba(0,0,0,.14);
  --gut:clamp(1.25rem,5vw,5rem);
  --band:clamp(4.5rem,11vw,11rem);
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:4rem}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;overflow-x:clip;
  background:var(--ink);color:var(--paper);
  font-family:'Archivo',system-ui,sans-serif;
  font-size:clamp(1rem,.28vw + .94rem,1.08rem);
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  font-variant-numeric:tabular-nums;
}
figure,blockquote,dl,dd,p,h1,h2,h3,table{margin:0}
h1,h2,h3{font-stretch:110%;font-weight:800;letter-spacing:-.034em;line-height:1;text-wrap:balance}
h1{font-size:clamp(1.9rem,4vw,3.4rem);letter-spacing:-.035em}
h2{font-size:clamp(1.5rem,2.5vw,2.2rem)}
h3{font-size:clamp(1.02rem,1.15vw,1.18rem);letter-spacing:-.015em;line-height:1.25}
a{color:inherit}
img{display:block;max-width:100%}
:focus-visible{outline:2px solid var(--paper);outline-offset:4px}
.wrap{width:min(100% - (var(--gut) * 2),88rem);margin-inline:auto}
.prose{max-width:56ch}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.skip{position:absolute;left:-9999px}
.skip:focus{left:.5rem;top:.5rem;z-index:99;background:var(--paper);color:var(--ink);padding:.7rem 1rem}
.quiet{color:var(--silver)}
.lab{font-size:.72rem;font-weight:700;font-stretch:100%;letter-spacing:.18em;text-transform:uppercase;color:var(--silver)}

/* ── header ──────────────────────────────────────────────────── */
.head{
  position:fixed;inset:0 0 auto;z-index:90;
  transition:background-color .3s,border-color .3s,backdrop-filter .3s;
  border-bottom:1px solid transparent;
}
.head.is-stuck{
  background:rgba(11,11,11,.9);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  border-bottom-color:var(--hair);
}
.head.is-stuck .head__in{padding-block:.5rem}
.head.is-stuck .head__logo{width:clamp(6rem,8vw,7rem)}
.head__in{position:relative;display:flex;flex-wrap:wrap;align-items:center;gap:.6rem var(--gut);padding-block:.7rem}
/* no transition on width: animating it forces layout every frame. The size
   change is a single snap on one class toggle, which costs one layout pass. */
.head__logo{width:clamp(8.5rem,14vw,11.5rem);flex:none}
.head__logo img{width:100%;height:auto;filter:invert(1)}

nav ul{display:flex;gap:1.5rem;list-style:none;margin:0;padding:0}
nav a{text-decoration:none;font-size:.9rem;font-weight:600;color:var(--silver-2)}
nav a:hover,nav a:focus-visible{color:var(--paper)}
.head__tel{
  margin-left:auto;display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:.5rem 1.15rem;white-space:nowrap;
  background:var(--paper);color:var(--ink);
  text-decoration:none;font-weight:800;font-stretch:105%;font-size:.9rem;letter-spacing:-.005em;
  transition:background-color .2s;
}
.head__tel:hover,.head__tel:focus-visible{background:var(--silver-2)}
.burger{
  margin-left:auto;display:none;align-items:center;gap:.5rem;min-height:48px;
  background:none;border:0;color:inherit;font:inherit;font-size:.9rem;font-weight:700;cursor:pointer;
}
.burger svg{width:22px;height:22px}
.burger[aria-expanded="true"] .bars,.burger .x{display:none}
.burger[aria-expanded="true"] .x{display:block}
@media (max-width:61.99rem){
  .burger{display:inline-flex}
  .head__nav{display:none;order:9;width:100%;background:var(--ink);border-top:1px solid var(--hair)}
  .head__nav[data-open]{display:block}
  .head__nav ul{flex-direction:column;gap:0}
  .head__nav a{display:block;padding-block:1rem;min-height:48px;border-bottom:1px solid var(--hair)}
  /* the number would wrap onto its own line over the photograph; the hero's
     call button sits a thumb away, so the header keeps to logo and menu */
  .head__tel{display:none}
}

/* ── hero ────────────────────────────────────────────────────── */
/* One frame at both sizes, so the crop points are tuned per breakpoint to keep the
   logo on the wall in shot rather than a blank stretch of it. Holding image until
   Carol shoots landscape frames. */
.hero{position:relative;display:grid;min-height:100svh;place-items:end center;background:var(--ink)}
.hero__media{position:absolute;inset:0;background:#000;overflow:clip}
.hero__media::after{content:"";position:absolute;inset:0;
  background:linear-gradient(to bottom,rgba(11,11,11,.5),rgba(11,11,11,.38) 26%,rgba(11,11,11,.72) 62%,rgba(11,11,11,.96))}
.hero__media img{
  width:100%;height:100%;object-fit:cover;object-position:50% 42%;
  /* a 256px source cannot be sharp at this size, so the blur is deliberate:
     it reads as depth of field rather than a failed upscale. Swap the filter out
     the moment Carol sends the original. */
  filter:saturate(1.25) contrast(1.05) brightness(.6) blur(8.5px);
  transform:scale(1.06);
}
@media (min-width:62rem){ .hero__media img{object-position:50% 46%;filter:saturate(1.25) contrast(1.05) brightness(.64) blur(11px)} }
.hero__body{
  position:relative;z-index:2;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;width:min(100% - (var(--gut) * 2),88rem);
  /* bottom aligned: the review is the last thing before the fold */
  padding-block:clamp(8rem,24vh,13rem) clamp(2.25rem,5vh,3.5rem);
}
.hero__body h1,.hero__body .hero__deck{margin-inline:auto}
.hero__cta,.hero__stars{justify-content:center}
.hero h1{font-size:clamp(2rem,4.4vw,3.75rem);letter-spacing:-.04em;max-width:22ch}
.hero__deck{margin-top:clamp(.9rem,1.5vw,1.25rem);font-size:clamp(1rem,1.05vw,1.1rem);max-width:52ch;color:var(--silver-2)}
.hero__quote{
  margin-top:clamp(2.25rem,6vh,4rem);padding-top:clamp(1.4rem,3vh,2rem);
  border-top:1px solid var(--hair);max-width:42ch;
}
.hero__quote blockquote{
  font-family:'Caveat',ui-rounded,cursive;
  font-size:clamp(1.15rem,1.4vw,1.4rem);line-height:1.32;color:#e7e7e4;
}
.hero__quote cite{display:block;margin-top:.65rem;font-style:normal;
  font-size:.72rem;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--silver)}
.hero__cta{display:flex;flex-wrap:wrap;gap:.9rem 1.1rem;margin-top:clamp(1.75rem,3.5vw,2.5rem);align-items:center}
.btn{
  display:inline-flex;align-items:center;justify-content:center;min-height:52px;
  padding:.8rem 1.4rem;background:var(--paper);color:var(--ink);
  text-decoration:none;font-weight:800;font-stretch:105%;font-size:.95rem;letter-spacing:-.008em;
  transition:background-color .2s,color .2s;
}
.btn:hover,.btn:focus-visible{background:var(--silver-2)}
.btn--ghost{background:none;color:var(--paper);box-shadow:inset 0 0 0 1px var(--hair);padding-inline:1.3rem}
.btn--ghost:hover,.btn--ghost:focus-visible{background:rgba(255,255,255,.08);box-shadow:inset 0 0 0 1px rgba(255,255,255,.4)}
.hero__stars{margin-top:clamp(1.6rem,3vw,2.2rem);display:flex;align-items:baseline;gap:.6rem;flex-wrap:wrap}
.hero__stars b{font-size:.98rem;font-weight:800}

/* the video is the motion; no second entrance effect competing with it */

/* ── sections ────────────────────────────────────────────────── */
.sec{padding-block:var(--band)}
.sec--paper{background:var(--paper);color:var(--ink)}
.sec--paper .lab{color:#5a5a56}
.sec--paper .quiet{color:#44443f}
.lede{font-size:clamp(1.15rem,1.7vw,1.55rem);line-height:1.32;font-weight:600;letter-spacing:-.018em;max-width:38ch}

/* spare ruled rows */
.sec--paper .rows{border-color:var(--hair-dark)}
.rows > div{padding-block:clamp(1.4rem,2.6vw,2rem);border-bottom:1px solid var(--hair);display:grid;gap:.4rem}
.sec--paper .rows > div{border-color:var(--hair-dark)}
@media (min-width:52rem){ .rows > div{grid-template-columns:minmax(0,17rem) minmax(0,54ch);gap:var(--gut);align-items:baseline} }

/* full bleed photograph */
.bleed{position:relative;background:#000;margin:0}
.bleed img{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;filter:contrast(1.03) brightness(.94)}
@media (min-width:34rem){ .bleed img{aspect-ratio:16/9} }
@media (min-width:62rem){ .bleed img{aspect-ratio:21/9} }
.bleed figcaption{
  position:absolute;inset:auto 0 0;padding-block:clamp(1.5rem,4vw,3rem);
  background:linear-gradient(to top,rgba(0,0,0,.85) 15%,transparent);
}
.bleed h2{max-width:22ch}

/* ── the sheet: one paper element, the proof ─────────────────── */
.sheet{margin-top:clamp(2rem,4vw,3rem);border:1px solid var(--hair-dark)}
.sheet__cap,.sheet__foot{padding:.85rem 1.1rem}
.sheet__cap{border-bottom:1px solid var(--hair-dark)}
.sheet__foot{border-top:1px solid var(--hair-dark)}
table{border-collapse:collapse;width:100%;font-size:.98rem}
th,td{text-align:left;padding:.85rem 1.1rem;border-bottom:1px solid var(--hair-dark);vertical-align:baseline}
thead th{font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;color:#5a5a56;white-space:nowrap}
tbody tr:last-child td{border-bottom:0}
td.wk{font-weight:800;font-stretch:110%}
td.load{font-weight:800;white-space:nowrap}
td.note-cell{color:#44443f}
@media (max-width:47.99rem){
  thead{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
  tbody tr{display:grid;grid-template-columns:auto auto 1fr;gap:.2rem 1rem;padding:1rem 1.1rem;border-bottom:1px solid var(--hair-dark);align-items:baseline}
  tbody td{border:0;padding:0}
  td.wk::before{content:"Week ";font-stretch:100%;font-weight:700;font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:#5a5a56}
  td.note-cell{grid-column:1/-1;margin-top:.15rem}
  td.note-cell:empty{display:none}
}

/* ── prices ──────────────────────────────────────────────────── */
.svc__row{padding-block:clamp(1.6rem,3vw,2.4rem);border-bottom:1px solid var(--hair);display:grid;gap:.6rem}
@media (min-width:52rem){ .svc__row{grid-template-columns:minmax(0,18rem) minmax(0,46ch) auto;gap:var(--gut);align-items:start} }
.svc__price{font-stretch:110%;font-weight:800;font-size:clamp(1.3rem,1.8vw,1.7rem);letter-spacing:-.025em;white-space:nowrap;margin-left:auto}
.svc__price span{display:block;font-stretch:100%;font-weight:600;font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--silver)}

/* ── reviews ─────────────────────────────────────────────────── */
.revs{margin-top:clamp(2rem,4vw,3.5rem);display:grid;gap:clamp(2rem,4vw,3.5rem) var(--gut)}
@media (min-width:52rem){ .revs{grid-template-columns:1fr 1fr} }
.rev blockquote{font-size:clamp(1rem,1.1vw,1.1rem);line-height:1.5;letter-spacing:-.008em}
.rev cite{display:block;margin-top:.9rem;font-style:normal}

/* ── about ───────────────────────────────────────────────────── */
.about{display:grid;gap:clamp(2rem,5vw,4rem)}
@media (min-width:62rem){ .about{grid-template-columns:minmax(0,24rem) minmax(0,1fr);align-items:start} }
.about figure img{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;filter:contrast(1.03)}
.addon h3{margin-bottom:.7rem}
.addon p + p{margin-top:.9rem}
.addon p{max-width:62ch}

/* ── book ────────────────────────────────────────────────────── */
.book{display:grid;gap:clamp(2rem,4vw,3.5rem);margin-top:clamp(2rem,4vw,3rem)}
@media (min-width:52rem){ .book{grid-template-columns:1fr 1fr} }
dd{font-weight:600}
dd a{text-decoration:none;border-bottom:1px solid var(--silver)}
.embed{border:1px solid var(--hair);padding:1.2rem;display:grid;gap:.6rem;align-content:start;min-height:14rem}

/* ── footer ──────────────────────────────────────────────────── */
.foot{border-top:1px solid var(--hair);padding-block:clamp(2.5rem,5vw,4rem) clamp(2rem,4vw,3rem)}
.foot__in{display:flex;flex-wrap:wrap;gap:1.25rem var(--gut);align-items:center;
  margin-top:clamp(2.5rem,5vw,3.5rem);padding-top:clamp(1.5rem,3vw,2rem);border-top:1px solid var(--hair)}
.foot__nav{margin-left:auto;display:flex;flex-wrap:wrap;gap:1.4rem}
.foot__nav a{text-decoration:none;font-size:.9rem;font-weight:600;color:var(--silver-2)}
.foot__nav a:hover{color:var(--paper)}
.foot__logo{width:8.5rem;flex:none}
.foot__logo img{width:100%;height:auto;filter:invert(1)}
.foot p{font-size:.85rem;color:var(--silver)}
section{scroll-margin-top:1rem}

/* ── WhatsApp enquiry tab, shared snippet ── */
/* ---------------------------------------------------------------
   WhatsApp enquiry tab
   Floating tap-to-chat with the message already written for them.
   Icon only, no text label, the glyph does the explaining.
   Inherits the host site's --pill / --ease / --card / --ink tokens
   if they exist, falls back to sane values if they don't.
   --------------------------------------------------------------- */

/* tokens live on :root, not on .wa-tap. the bubble is a sibling of the button,
   so anything scoped to .wa-tap is invisible to it. */
:root{
  /* deeper than stock WhatsApp green (#25d366) on purpose. the stock neon reads as
     a bolted-on widget next to most brand palettes, this still reads as WhatsApp
     instantly but sits in the design. stock green is one line away if wanted. */
  --wa:#1fa855;                /* button fill */
  --wa-deep:#17904a;           /* button fill on hover */

  /* neutral elevation, not a coloured glow. a tinted halo is the giveaway of a
     bolted-on chat widget, plain shadow reads as part of the site. */
  --wa-shadow:0 12px 28px -10px rgba(0,0,0,.6), 0 2px 6px rgba(0,0,0,.3);
  --wa-shadow-hover:0 18px 36px -12px rgba(0,0,0,.68), 0 2px 6px rgba(0,0,0,.32);

  --wa-gap:clamp(.9rem,2.2vw,1.4rem);
  --wa-size:60px;              /* button diameter, the bubble offsets off this */
}

.wa-tap,.wa-peek,.wa-peek *{
  box-sizing:border-box;         /* don't rely on the host site having a reset */
}

.wa-tap{
  position:fixed;
  right:var(--wa-gap,1.25rem);
  bottom:calc(var(--wa-gap,1.25rem) + env(safe-area-inset-bottom,0px));
  z-index:85;                     /* under a typical fixed header, over page content */

  display:grid;
  place-items:center;
  width:var(--wa-size);
  height:var(--wa-size);
  border-radius:50%;
  background:var(--wa);
  color:#fff;
  text-decoration:none;           /* don't rely on the host site's link reset */
  -webkit-tap-highlight-color:transparent;
  box-shadow:var(--wa-shadow);

  /* entry state, flipped by data-wa-state="in" once the page has settled */
  opacity:0;
  transform:translateY(14px) scale(.94);
  transition:opacity .45s var(--ease,cubic-bezier(.16,1,.3,1)),
             transform .45s var(--ease,cubic-bezier(.16,1,.3,1)),
             background .22s ease,
             box-shadow .28s var(--ease,cubic-bezier(.16,1,.3,1));
}
.wa-tap[data-wa-state="in"]{opacity:1;transform:none}

.wa-tap:hover{
  background:var(--wa-deep);
  box-shadow:var(--wa-shadow-hover);
}
.wa-tap[data-wa-state="in"]:hover{transform:translateY(-2px)}
.wa-tap:active{transform:translateY(0) scale(.96)}

.wa-tap svg{width:31px;height:31px;fill:currentColor}

/* the nudge bubble: fires once, then remembers it was dismissed */
.wa-peek{
  position:fixed;
  right:var(--wa-gap,1.25rem);
  bottom:calc(var(--wa-size,60px) + var(--wa-gap,1.25rem) + .65rem + env(safe-area-inset-bottom,0px));
  z-index:86;
  width:max-content;                    /* hugs short labels, wraps long ones */
  max-width:min(17rem,calc(100vw - 2.5rem));
  padding:.95rem 2.1rem .95rem 1.05rem;
  border-radius:16px 16px 6px 16px;
  background:var(--card,#fff);
  color:var(--ink,#282320);
  border:1px solid var(--line,rgba(0,0,0,.1));
  box-shadow:0 20px 46px -22px rgba(0,0,0,.42);
  font-family:inherit;
  font-size:.88rem;
  line-height:1.45;
  text-align:left;
  opacity:0;
  transform:translateY(8px) scale(.96);
  transform-origin:100% 100%;
  transition:opacity .4s var(--ease,cubic-bezier(.16,1,.3,1)),
             transform .4s var(--ease,cubic-bezier(.16,1,.3,1));
}
.wa-peek[data-wa-state="in"]{opacity:1;transform:none}
.wa-peek[hidden]{display:none}

.wa-peek-close{
  position:absolute;
  top:.3rem;
  right:.3rem;
  width:30px;
  height:30px;
  display:grid;
  place-items:center;
  border:0;
  background:none;
  color:var(--ink-soft,#6b625a);
  font-size:1.05rem;
  line-height:1;
  cursor:pointer;
  border-radius:50%;
  transition:color .2s ease,background .2s ease;
}
.wa-peek-close:hover{color:var(--ink,#282320);background:rgba(0,0,0,.06)}

/* --- collision handling ------------------------------------------------ */

/* get out of the way of an open mobile nav. one selector per pattern we use:
   .site-header.menu-open is Yerby, .mobile-menu.open is the ATA site, .nav-open
   is the generic fallback. add the site's own class here if it differs. */
body:has(.site-header.menu-open) .wa-tap,
body:has(.site-header.menu-open) .wa-peek,
body:has(.mobile-menu.open) .wa-tap,
body:has(.mobile-menu.open) .wa-peek,
body:has(.nav-open) .wa-tap,
body:has(.nav-open) .wa-peek,
body:has(.head__nav[data-open]) .wa-tap,
body:has(.head__nav[data-open]) .wa-peek{
  opacity:0;
  pointer-events:none;
  transform:translateY(10px) scale(.94);
}

/* on narrow screens the cookie banner goes full width, so sit above it */
@media(max-width:560px){
  body:has(.cookie-banner:not([hidden])) .wa-tap{bottom:calc(var(--wa-gap,1.25rem) + 9.5rem + env(safe-area-inset-bottom,0px))}
  body:has(.cookie-banner:not([hidden])) .wa-peek{display:none}
}

@media(prefers-reduced-motion:reduce){
  .wa-tap,.wa-peek{transition:none}
  .wa-tap[data-wa-state="in"],.wa-peek[data-wa-state="in"]{transform:none}
  .wa-tap[data-wa-state="in"]:hover,.wa-tap:active{transform:none}
}

/* print / no-js: no point showing it */
@media print{.wa-tap,.wa-peek{display:none}}
html:not(.js) .wa-tap,html:not(.js) .wa-peek{display:none}


/* ── section rhythm: alternate dense and quiet rather than one gap forever ── */
.sec--tight{padding-block:clamp(3.5rem,8vw,7rem)}
.mid{max-width:44rem;margin-inline:auto;text-align:center}
.mid .lede{margin-top:1rem;margin-inline:auto}

/* three across, using the width instead of leaving it empty */
.triple{margin-top:clamp(2.5rem,5vw,4rem);display:grid;gap:clamp(1.6rem,3vw,2.5rem);
  border-top:1px solid var(--hair);padding-top:clamp(1.6rem,3vw,2.5rem)}
@media (min-width:52rem){ .triple{grid-template-columns:repeat(3,1fr);gap:clamp(2rem,4vw,4rem)} }
.triple h3{margin-bottom:.5rem}
.triple p{max-width:38ch}

/* heading one side, the explanation the other */
.split{display:grid;gap:1.2rem}
@media (min-width:62rem){
  .split{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:clamp(2.5rem,5vw,5rem);align-items:end}
}
.split p{max-width:46ch}

.bleed__h{display:block;margin-top:.5rem;font-size:clamp(1.5rem,2.5vw,2.2rem);
  font-weight:800;font-stretch:110%;letter-spacing:-.034em;line-height:1.02}

/* prices: the figure is the loudest thing in the section */
.price{margin-top:clamp(2rem,4vw,3.5rem);border-top:1px solid var(--hair)}
.price__row{padding-block:clamp(1.8rem,3.5vw,3rem);border-bottom:1px solid var(--hair);
  display:grid;gap:.9rem}
@media (min-width:52rem){
  .price__row{grid-template-columns:minmax(0,15rem) minmax(0,1fr);gap:clamp(2rem,5vw,5rem);align-items:start}
}
.price__fig{
  font-stretch:110%;font-weight:800;letter-spacing:-.045em;line-height:.9;
  font-size:clamp(3rem,6vw,5.25rem);white-space:nowrap;
}
.price__fig span{display:block;margin-top:.55rem;font-stretch:100%;font-weight:600;
  font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;color:var(--silver);white-space:nowrap}
.price__fig--sm{font-size:clamp(2rem,3.4vw,3rem);color:var(--silver-2)}
.price__row--add{border-bottom:0}
.price__row--add h3,.price__row--add p{color:var(--silver-2)}
.price__row p.quiet{max-width:60ch}

/* proof: the score carries it */
.score{display:grid;gap:1rem;align-items:center}
@media (min-width:44rem){ .score{grid-template-columns:auto minmax(0,1fr);gap:clamp(1.5rem,4vw,3.5rem)} }
.score__fig{font-stretch:110%;font-weight:800;letter-spacing:-.05em;line-height:.85;
  font-size:clamp(4rem,9vw,8rem)}
.score + .revs{margin-top:clamp(2.5rem,5vw,4rem);border-top:1px solid var(--hair);padding-top:clamp(2rem,4vw,3rem)}
.revs{display:grid;gap:clamp(2rem,4vw,3.5rem) clamp(2rem,4vw,4rem)}
@media (min-width:48rem){ .revs{grid-template-columns:1fr 1fr} }
@media (min-width:72rem){ .revs{grid-template-columns:repeat(3,1fr)} }
.rev blockquote{font-size:clamp(1.05rem,1.25vw,1.22rem);line-height:1.5;letter-spacing:-.01em}
.rev cite{display:block;margin-top:.85rem;font-style:normal}

@media (min-width:62rem){ .about{grid-template-columns:minmax(0,26rem) minmax(0,1fr);gap:clamp(2.5rem,6vw,5rem)} }
.book{margin-top:clamp(2.5rem,5vw,4rem);padding-top:clamp(2rem,4vw,3rem);border-top:1px solid var(--hair)}


/* ── in-content links ──────────────────────────────────────────── */
.link{
  display:inline-flex;align-items:baseline;gap:.4rem;
  text-decoration:none;font-weight:700;font-size:.95rem;
  color:var(--paper);border-bottom:1px solid rgba(255,255,255,.35);
  padding-bottom:2px;transition:border-color .2s,color .2s;
}
.link::after{content:"\2192";transition:transform .25s cubic-bezier(.16,1,.3,1)}
.link:hover,.link:focus-visible{border-bottom-color:var(--paper)}
.link:hover::after{transform:translateX(.25rem)}
.sec--paper .link{color:var(--ink);border-bottom-color:rgba(0,0,0,.3)}
.sec--paper .link:hover{border-bottom-color:var(--ink)}
.price__row h3 a{text-decoration:none;border-bottom:1px solid rgba(255,255,255,.28);padding-bottom:1px}
.price__row h3 a:hover{border-bottom-color:var(--paper)}
.more{margin-top:clamp(1.6rem,3vw,2.25rem)}

/* left aligned on purpose: the hero closes centred, so this changes gear */
.opener{display:grid;gap:1rem}
@media (min-width:62rem){
  .opener{grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:clamp(2.5rem,5vw,5rem);align-items:end}
}
.opener h2{max-width:20ch}
.opener p{max-width:44ch}
/* the band sits straight under the hero now, so it needs no top margin */
.hero + .bleed{margin-top:0}

/* Carol, in her own words, on the paper section */
.pull{
  margin-top:clamp(2rem,4vw,3rem);padding-top:clamp(1.5rem,3vw,2.25rem);
  border-top:1px solid var(--hair-dark);max-width:34rem;
}
.pull blockquote{
  font-family:'Caveat',ui-rounded,cursive;
  font-size:clamp(1.5rem,2.5vw,2.1rem);line-height:1.3;color:#e7e7e4;
}
.pull cite{display:block;margin-top:.9rem;font-style:normal;
  font-size:.72rem;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:#5a5a56}

/* two up, image contained inside the section rather than bled edge to edge */
.duo{display:grid;gap:clamp(2rem,4vw,3.5rem);align-items:start}
@media (min-width:62rem){
  .duo{grid-template-columns:minmax(0,1fr) minmax(0,40%);gap:clamp(2.5rem,5vw,5rem)}
  .duo--flip{grid-template-columns:minmax(0,44%) minmax(0,1fr)}
  .duo--flip figure{order:-1}
  /* Where the copy is genuinely shorter than the frame beside it, starting both
     at the top pools the whole difference into one hole under the text. Centring
     splits it, and the two columns read as a pair rather than one short one. */
  .duo--mid{align-items:center}
}
.shot img{width:100%;height:auto;filter:contrast(1.03)}
.shot figcaption{margin-top:.7rem;display:block}
.triple--stack{margin-top:clamp(2rem,4vw,3rem);border-top:1px solid var(--hair);padding-top:clamp(1.6rem,3vw,2.25rem)}
@media (min-width:52rem) and (max-width:61.99rem){ .triple--stack{grid-template-columns:repeat(3,1fr)} }
@media (min-width:62rem){ .triple--stack{grid-template-columns:1fr 1fr;gap:clamp(1.6rem,3vw,2.5rem)} }
/* the pull quote lives on the dark ground now */
.pull{border-top-color:var(--hair)}
.pull cite{color:var(--silver)}

/* NAP lives in the footer, said once. Address, hours and phone in the page body
   is a local ranking signal, so it stays on the homepage; it just stopped being
   printed twice within 200px of itself. */
.details{display:grid;gap:1.75rem;text-align:left}
@media (min-width:48rem){ .details{grid-template-columns:repeat(2,1fr)} }
@media (min-width:64rem){ .details{grid-template-columns:repeat(4,1fr)} }
.details div{display:block;border:0;padding:0}
.details dt{margin-bottom:.45rem;padding:0}
.details dd{font-weight:600}


/* the room as the ground. It reads as a band rather than a hero because of where it
   sits (a whole section after the hero, not directly under it), plus no viewport
   height, text left rather than centred, and type at section scale. */
.room{position:relative;padding-block:clamp(4.5rem,10vw,8rem);overflow:clip;background:#000}
.room__bg{position:absolute;inset:0}
.room__bg img{width:100%;height:100%;object-fit:cover;object-position:60% 55%;
  filter:contrast(1.02) brightness(.42) saturate(1.03)}
.room__bg::after{content:"";position:absolute;inset:0;
  background:linear-gradient(to right,rgba(11,11,11,.86),rgba(11,11,11,.55) 52%,rgba(11,11,11,.25))}
.room__say{position:relative;z-index:2;max-width:38rem}
.room__say h2{max-width:17ch}
.room__say p{margin-top:1.2rem;font-size:clamp(1.05rem,1.25vw,1.2rem);color:#e4e4e1;max-width:44ch}
.room__cap{margin-top:clamp(1.75rem,3.5vw,2.5rem)!important;color:var(--silver-2)!important}

/* the room at full column width: real scale, but it keeps the page margins so it
   cannot read as a second hero the way a bled band did */
.plate{margin-top:clamp(2rem,4vw,3rem)}
.plate img{width:100%;height:auto;filter:contrast(1.03)}
.plate figcaption{margin-top:.8rem;display:block}

/* ── review marquee ─────────────────────────────────────────────
   One set plus an aria-hidden clone, translated by exactly -50% so the
   loop is seamless. Transform only, so it never triggers layout. */
.belt{margin-top:clamp(2.5rem,5vw,4rem);overflow:hidden;
  mask-image:linear-gradient(to right,transparent,#000 6rem,#000 calc(100% - 6rem),transparent);
  -webkit-mask-image:linear-gradient(to right,transparent,#000 6rem,#000 calc(100% - 6rem),transparent)}
.belt__track{display:flex;width:max-content;animation:belt 90s linear infinite}
.belt:hover .belt__track,.belt:focus-within .belt__track{animation-play-state:paused}
.belt__set{display:flex;list-style:none;margin:0;padding:0}
.tick{
  flex:0 0 auto;width:min(24rem,78vw);
  margin-right:clamp(1.25rem,2.5vw,2rem);
  padding:clamp(1.4rem,2.5vw,1.9rem);
  border:1px solid var(--hair);
  display:flex;flex-direction:column;justify-content:space-between;gap:1.1rem;
}
.tick blockquote{font-size:1.02rem;line-height:1.5;letter-spacing:-.008em}
.tick cite{font-style:normal;font-size:.72rem;font-weight:700;letter-spacing:.18em;
  text-transform:uppercase;color:var(--silver)}
@keyframes belt{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}
@media (prefers-reduced-motion:reduce){
  /* no movement at all: it becomes a swipeable row instead */
  .belt{overflow-x:auto;mask-image:none;-webkit-mask-image:none}
  .belt__track{animation:none}
  .belt__set[aria-hidden="true"]{display:none}
}

/* her mark, large, centred in the section and hanging off the right edge.
   Decorative only: aria-hidden and pointer-events none. Opacity is kept at 6% so
   that where it does sit behind copy the local ground only lifts to about #1a1a1a,
   which leaves white body text far above the contrast floor. The section clips it
   so the overhang cannot widen the page. */
.sec--mark{position:relative;overflow:clip}
.mark{
  position:absolute;top:50%;right:-6vw;translate:0 -50%;
  width:clamp(20rem,46vw,46rem);height:auto;
  opacity:.06;filter:invert(1);
  pointer-events:none;user-select:none;z-index:0;
}
.sec--mark .wrap{position:relative;z-index:1}
@media (max-width:52rem){ .mark{width:22rem;right:-8vw;opacity:.05} }

/* the close is the page's one light section. Everything from the studio band down
   is near-black, so ending on paper gives the page a rhythm and answers the
   "it goes dark" problem properly rather than by swapping the photograph. */
.close{position:relative;overflow:clip;background:var(--paper);color:var(--ink)}
.close__bg{position:absolute;inset:0}
.close__bg img{width:100%;height:100%;object-fit:cover;object-position:50% 50%;
  filter:contrast(.9) brightness(1.5) saturate(.75)}
/* heaviest where the heading, body copy and buttons sit; opens up below them so
   the dumbbells read properly along the bottom edge */
.close__bg::after{content:"";position:absolute;inset:0;
  background:linear-gradient(to bottom,
    rgba(255,255,255,.93) 0%,
    rgba(255,255,255,.9) 52%,
    rgba(255,255,255,.78) 76%,
    rgba(255,255,255,.5) 100%)}
.close > .wrap{position:relative;z-index:1}
.close h2{color:var(--ink)}
.close .quiet{color:#3f3f3a}
/* buttons invert on the light ground */
.close .btn{background:var(--ink);color:var(--paper)}
.close .btn:hover,.close .btn:focus-visible{background:#2a2a27}
.close .btn--ghost{background:none;color:var(--ink);box-shadow:inset 0 0 0 1px rgba(0,0,0,.28)}
.close .btn--ghost:hover,.close .btn--ghost:focus-visible{background:rgba(0,0,0,.06);box-shadow:inset 0 0 0 1px var(--ink)}
.close :focus-visible{outline-color:var(--ink)}

/* ═══ interior pages ══════════════════════════════════════════════
   Rebuilt 15 Aug 2026. The first pass was a text document with photographs
   dropped into it. This one lets the pictures do the explaining and keeps the
   words to captions. Every photograph on an interior page has a person in it:
   the empty-room and equipment-still shots are the homepage's job. */

/* Full bleed and sharp. The homepage hero is centred, blurred and full height
   because its only source is a 256px thumbnail. This is an 18MP frame, so it
   runs sharp, sits shorter, and reads bottom left. Two different openings. */
.lead{position:relative;display:grid;align-items:end;min-height:100svh;
  background:#000;overflow:clip}
.lead__bg{position:absolute;inset:0}
.lead__bg img{width:100%;height:100%;object-fit:cover;object-position:46% 42%;
  /* the homepage hero is quiet, near black and soft, and type sits on calm ground.
     A sharp busy documentary frame at full brightness reads as a different site,
     so this recedes: darker, a little desaturated, the photograph as ground. */
  filter:contrast(1.02) saturate(.82) brightness(.52)}
.lead__bg::after{content:"";position:absolute;inset:0;background:
  linear-gradient(to top,rgba(11,11,11,.96) 4%,rgba(11,11,11,.82) 34%,
  rgba(11,11,11,.42) 62%,rgba(11,11,11,.44) 78%,rgba(11,11,11,.74) 100%)}
.lead__say{position:relative;z-index:2;
  /* bottom value clears the fixed WhatsApp tab and its peek bubble, which are
     anchored bottom right and would otherwise cover the review quote. */
  padding-block:clamp(8rem,18vh,12rem) clamp(3.5rem,16vh,9rem)}
/* type left, the client's own words bottom right. The right half of the frame was
   carrying nothing but photograph, and the quote read as an afterthought stuck to
   the bottom of a tall stack. Both sit on the baseline now. */
.lead__in{display:grid;gap:clamp(2rem,4.5vh,3rem)}
@media (min-width:62rem){
  .lead__in{grid-template-columns:minmax(0,1fr) minmax(0,30%);
    gap:clamp(2.5rem,5vw,5rem);align-items:end}
  .lead__in > .lead__quote{margin-top:0}
}
.lead h1{max-width:14ch}
.lead__line{margin-top:clamp(.9rem,1.6vw,1.3rem);color:#e6e6e3;
  font-size:clamp(1.05rem,1.15vw,1.22rem);max-width:40ch}
.lead .hero__cta{justify-content:flex-start;margin-top:clamp(1.75rem,3vw,2.5rem)}
/* the handwriting is the site's one human mark. It carries the homepage hero and
   it is what makes an interior page read as the same place. */
.lead__quote{margin-top:clamp(2rem,4.5vh,3rem);padding-top:clamp(1.2rem,2.5vh,1.6rem);
  border-top:1px solid var(--hair);max-width:38ch}
.lead__quote blockquote{font-family:'Caveat',ui-rounded,cursive;
  font-size:clamp(1.15rem,1.5vw,1.5rem);line-height:1.3;color:#ececeb}
.lead__quote cite{display:block;margin-top:.55rem;font-style:normal;font-size:.72rem;
  font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--silver)}
.lead .btn--ghost{box-shadow:inset 0 0 0 1px rgba(255,255,255,.4)}
.lead .btn--ghost:hover,.lead .btn--ghost:focus-visible{box-shadow:inset 0 0 0 1px rgba(255,255,255,.75)}


/* one statement at display size, alone on the page. The change of gear between
   a full bleed photograph and the grid below it. */


/* questions, kept short and kept last. They are here because people arrive with
   them, and because they are the part search engines quote back. */
.faq{margin-top:clamp(2rem,4vw,3rem);display:grid;gap:clamp(1.6rem,3vw,2.25rem)}
@media (min-width:56rem){ .faq{grid-template-columns:1fr 1fr;gap:clamp(2rem,3.5vw,2.75rem) var(--gut)} }
.faq h3{margin-bottom:.5rem}
.faq p{max-width:48ch;color:var(--silver-2)}

@media (min-width:72rem){ .revs--pair{grid-template-columns:1fr 1fr} }
.revs cite,.rev cite{font-size:.72rem;font-weight:700;letter-spacing:.18em;
  text-transform:uppercase;color:var(--silver)}
.rev blockquote{color:#e7e7e4}

/* A landscape frame in a two up column renders short and wide and reads as an
   afterthought next to a tall block of copy. Cropping to portrait matches the
   height of the text beside it. Scoped, so the homepage's square frame is
   left exactly as it was signed off. */
.shot--tall img{aspect-ratio:4/5;object-fit:cover;object-position:50% 44%}
@media (max-width:61.99rem){ .shot--tall img{aspect-ratio:3/2} }

/* ── paper price block ────────────────────────────────────────────
   5,000px of unbroken near black was the real problem with this page, and it is
   the same note she made on the homepage. The homepage answers it by ending
   light; an interior page answers it with one paper block in the middle. */
.sec--paper .price,.sec--paper .price__row{border-color:var(--hair-dark)}
.sec--paper .price__fig span{color:#5a5a56}
.sec--paper .price__fig--sm{color:#3f3f3a}
.sec--paper .price__row--add h3,.sec--paper .price__row--add p{color:#44443f}
/* the mark is dark artwork, so on paper it must not invert */
.sec--paper .mark{filter:none;opacity:.07}


/* square rather than 4:5, so a two up frame stops leaving a hole beside
   short copy. Matches the homepage's square frame. */
.shot--tall img{aspect-ratio:1/1}
/* Squaring a 3:4 portrait leaves the subject's face in the top third and hands
   the foreground to whatever she is sitting behind. Pulling the crop up puts
   Carol's face where the eye lands. Scoped, because the frames on the one to one
   page are already framed on the movement rather than on a person. */
.shot--face img{object-position:50% 22%}
/* the row heading was sitting flush on its paragraph. Applies on both pages;
   it is a legibility fix rather than a change of look. */
.price__row h3{margin-bottom:.45rem}

/* ── split band ───────────────────────────────────────────────────
   Replaces the text-over-photograph band on interior pages. That treatment is
   the homepage's and reading it twice made this page feel like a reprint of it.
   Photograph hard to one edge, copy on flat ground beside it, no overlay. */
.split{display:grid;background:#000;overflow:clip}
.split__media img{display:block;width:100%;height:100%;object-fit:cover;aspect-ratio:3/2}
.split__say{padding-block:clamp(2.75rem,7vw,5rem);padding-inline:var(--gut)}
@media (min-width:62rem){
  .split{grid-template-columns:minmax(0,50%) minmax(0,50%);align-items:center;
    min-height:min(76svh,40rem)}
  .split__media img{aspect-ratio:1/1}
  .split__say{padding-block:clamp(3.5rem,6vw,6rem);
    padding-inline:clamp(2.5rem,5vw,5rem) var(--gut)}
}
.split h2{max-width:18ch}
.split p{margin-top:1.15rem;color:#e4e4e1;max-width:44ch;font-size:clamp(1.02rem,1.15vw,1.15rem)}
.split .lab{margin-top:clamp(1.5rem,3vw,2.25rem);color:var(--silver-2)}

/* ── one price, on paper ──────────────────────────────────────────
   A second figure on a page about the studio hour read as a different offer.
   The online add-on belongs on the online coaching page. */
.price__row:last-child{border-bottom:0}
.sec--paper .btn{background:var(--ink);color:var(--paper)}
.sec--paper .btn:hover,.sec--paper .btn:focus-visible{background:#2a2a27}
.sec--paper :focus-visible{outline-color:var(--ink)}

/* ── reviews, three across with a rule each ───────────────────────
   Two at display size read as odd because they were unequal lengths carrying
   too much weight. A ruled set of three reads as evidence. */
.revs--three{grid-template-columns:1fr!important}
@media (min-width:52rem){ .revs--three{grid-template-columns:repeat(3,1fr)!important} }
.rev--mid{border-top:1px solid var(--hair);padding-top:clamp(1.2rem,2.5vw,1.7rem)}
.rev--mid blockquote{font-size:clamp(1.02rem,1.15vw,1.16rem);line-height:1.45;color:#e7e7e4}

/* ── accordion ────────────────────────────────────────────────────
   Answers stay in the DOM at all times, so crawlers and the FAQ markup still
   see them. Default CSS leaves every panel open: the script is what collapses
   them, so with JS broken nothing becomes unreadable. */
.acc{border-top:1px solid var(--hair)}
.acc:last-of-type{border-bottom:1px solid var(--hair)}
.acc__h{margin:0}
.acc__btn{width:100%;display:flex;align-items:center;justify-content:space-between;
  gap:1.5rem;padding-block:clamp(1.1rem,2.2vw,1.5rem);min-height:56px;
  background:none;border:0;color:inherit;font:inherit;text-align:left;cursor:pointer;
  font-weight:800;font-stretch:110%;letter-spacing:-.015em;
  font-size:clamp(1.02rem,1.2vw,1.2rem);transition:color .2s}
.acc__btn:hover{color:var(--silver-2)}
.acc__ico{flex:none;width:17px;height:17px;
  transition:transform .32s cubic-bezier(.16,1,.3,1)}
.acc__btn[aria-expanded="true"] .acc__ico{transform:rotate(45deg)}
/* max-height is a layout animation and the detector is right to flag it. It is
   suppressed for this file on purpose: there is no compositor-only way to make a
   panel collapse and pull the content below it up. clip-path animates cheaply but
   leaves the gap behind. One 380ms panel of four lines is a fair price. */
.acc__panel{overflow:hidden;transition:max-height .38s cubic-bezier(.16,1,.3,1)}
.acc__panel p{padding-bottom:clamp(1.1rem,2.2vw,1.6rem);max-width:62ch;color:var(--silver-2)}
@media (prefers-reduced-motion:reduce){
  .acc__panel,.acc__ico{transition:none}
}

/* ── the last thing on the page is an ask ─────────────────────────── */
.fin{padding-block:clamp(4rem,9vw,7rem);text-align:center}
.fin h2{max-width:22ch;margin-inline:auto}
.fin p{margin-top:1.15rem;margin-inline:auto;max-width:42ch;color:var(--silver-2)}
.fin .hero__cta{justify-content:center;margin-top:clamp(1.9rem,3.5vw,2.6rem)}
.fin .lab{margin-top:clamp(2rem,4vw,2.75rem)}
/* accordions run full width in a single column. Two columns of drop downs means
   opening one shunts only half the page, which reads as a glitch. */
.faq--acc{display:block!important;margin-top:clamp(2rem,4vw,3rem)}
/* .hero__cta centres by default for the homepage hero; inside a price row it has
   to sit under the copy it belongs to. */
.price__row .hero__cta{justify-content:flex-start}
/* the longest question wraps on a narrow screen, and 1.25 is tight for two lines
   of bold text in front of an audience that skews older. Scoped, so the
   homepage's h3s keep the leading they were signed off with. */
.acc__btn{line-height:1.35}

/* cs-25 is a landscape frame with the head high in it. A hero crop that centres
   vertically cuts her forehead, so this page pins the crop near the top. */
.lead--portrait .lead__bg img{object-position:47% 8%}

/* ── enquiry form ─────────────────────────────────────────────────
   Labels sit above their fields and stay visible. Placeholder-as-label
   disappears the moment someone types, which is exactly when a 60 year old
   filling this in on a phone wants to check what the box was asking for.
   16px minimum on inputs, because anything smaller makes iOS zoom the page
   on focus and the layout jumps under their thumb. */
.enq{display:grid;gap:clamp(1.1rem,2.4vw,1.5rem);max-width:44rem;margin-top:clamp(1.8rem,4vw,2.6rem)}
@media (min-width:44rem){ .enq__pair{display:grid;grid-template-columns:1fr 1fr;gap:inherit} }
.enq__row{display:grid;gap:.5rem;align-content:start}
.enq__lab{font-size:.72rem;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--silver)}
.enq__lab span{text-transform:none;letter-spacing:0;font-weight:500;color:#7e7e7c}
.enq__in{
  width:100%;min-height:54px;padding:.85rem 1rem;
  background:rgba(255,255,255,.04);color:var(--paper);
  border:1px solid var(--hair);border-radius:0;
  font:inherit;font-size:1rem;line-height:1.4;
  transition:border-color .2s,background-color .2s;
}
textarea.enq__in{min-height:9.5rem;resize:vertical}
.enq__in::placeholder{color:#6f6f6d}
.enq__in:hover{border-color:rgba(255,255,255,.28)}
.enq__in:focus-visible{outline:2px solid var(--paper);outline-offset:2px;border-color:transparent;background:rgba(255,255,255,.07)}
.enq__in[aria-invalid="true"]{border-color:#e2564d}
.enq__err{font-size:.85rem;color:#f0918a;min-height:0}
.enq__err:empty{display:none}
/* Off-screen rather than display:none. A bot reading the DOM fills anything it
   can find; hidden-by-display is the one convention they all skip. */
.enq__hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.enq__foot{display:flex;flex-wrap:wrap;gap:1rem;align-items:center;margin-top:.4rem}
.enq__note{font-size:.9rem;color:var(--silver);max-width:46ch}
.enq__say{margin-top:1rem;font-size:1rem}
.enq__say[data-state="bad"]{color:#f0918a}
.enq [type="submit"][data-busy]{opacity:.6;pointer-events:none}

/* A contact page opening at a full 100svh buries the form under a photograph
   nobody came for, but opening on bare type under the nav reads as a different
   site to the other three pages. Shorter hero, same treatment. */
.lead--short{min-height:62svh}
@media (max-width:52rem){ .lead--short{min-height:56svh} }
.lead--short .lead__say{padding-block:clamp(6rem,14vh,9rem) clamp(3rem,10vh,5rem)}

/* Media on the right. Two split bands running down one page both anchored left
   reads as a template; alternating them reads as a spread. */
@media (min-width:62rem){
  .split--flip .split__media{order:2}
  .split--flip .split__say{padding-inline:var(--gut) clamp(2.5rem,5vw,5rem)}
}
/* a portrait frame cropped square centres on the middle of the body, which puts
   the subject's head out of shot. */
.split__media img.is-tall{object-position:50% 34%}

/* ── the review wall ──────────────────────────────────────────────
   CSS columns balance themselves, and with 38 reviews running from 29 to 780
   characters the balancing punched large holes down the page. The columns are
   filled at build time instead, so each one stacks tight and the ragged bottom
   edge is the only unevenness left. */
.wall{display:grid;gap:0 clamp(2rem,4vw,4rem)}
@media (min-width:48rem){ .wall{grid-template-columns:1fr 1fr} }
@media (min-width:75rem){ .wall{grid-template-columns:repeat(3,1fr)} }
.wall__col{display:grid;align-content:start;gap:clamp(1.6rem,3vw,2.4rem)}
.wall .rev{padding-top:clamp(1rem,2.2vw,1.4rem);border-top:1px solid var(--hair)}
.wall .rev blockquote{font-size:clamp(.98rem,1vw,1.03rem);line-height:1.55;
  letter-spacing:-.006em;color:#d8d8d5}
.wall .rev cite{margin-top:.7rem}
.when{display:block;margin-top:.2rem;font-size:.68rem;letter-spacing:.14em;
  text-transform:uppercase;color:#6f6f6d;font-weight:600}

/* the three that carry the page, set at display size so the eye has somewhere to
   land before it meets the wall */
.feat{display:grid;gap:clamp(2.2rem,5vw,3.5rem);margin-top:clamp(2.5rem,5vw,4rem)}
@media (min-width:62rem){ .feat{grid-template-columns:repeat(3,1fr)} }
.feat figure{margin:0;display:grid;align-content:start}
.feat blockquote{font-stretch:105%;font-weight:600;letter-spacing:-.022em;
  font-size:clamp(1.25rem,1.9vw,1.7rem);line-height:1.28}
.feat cite{display:block;margin-top:1.1rem;font-style:normal}

/* a heading per group, so the wall reads as an argument rather than a dump */
/* nine reviews, not thirty five, so they can breathe and sit a size up */
.wall--rest{margin-top:clamp(3rem,6vw,5rem);border-top:1px solid var(--hair);
  padding-top:clamp(2.5rem,5vw,4rem)}
.wall--rest .rev blockquote{font-size:clamp(1rem,1.08vw,1.12rem);line-height:1.58}
.wall--rest .wall__col{gap:clamp(2.2rem,4vw,3.2rem)}

.band{margin-top:clamp(3.5rem,7vw,6rem)}
.band > h2{font-size:clamp(1.5rem,2.6vw,2.2rem);letter-spacing:-.03em}
.band > p{margin-top:.6rem;color:var(--silver);max-width:52ch}
.band .wall{margin-top:clamp(1.8rem,3.5vw,2.6rem)}

/* ── cookie ask ───────────────────────────────────────────────────
   Bottom left, because the WhatsApp tab owns the bottom right. Sits above the
   page rather than across it: a bar that covers the hero on a phone loses more
   enquiries than analytics is worth. Both buttons carry the same weight, which
   is not only good manners, it is what the ICO expects. */
.consent{
  position:fixed;left:var(--wa-gap);bottom:var(--wa-gap);z-index:60;
  width:min(26rem,calc(100vw - (var(--wa-gap) * 2)));
  background:var(--paper);color:var(--ink);
  padding:clamp(1.1rem,2.4vw,1.4rem);
  box-shadow:0 18px 40px -14px rgba(0,0,0,.6),0 2px 8px rgba(0,0,0,.28);
  opacity:0;transform:translateY(12px) scale(.98);
  transition:opacity .32s ease,transform .32s cubic-bezier(.16,1,.3,1);
}
.consent[data-consent-state="in"]{opacity:1;transform:none}
.consent[data-consent-state="out"]{opacity:0;transform:translateY(8px) scale(.98)}
.consent__say{font-size:.92rem;line-height:1.5;color:#33332f}
.consent__say a{color:var(--ink)}
.consent__act{display:flex;flex-wrap:wrap;gap:.6rem;margin-top:.9rem}
.consent__act button{
  flex:1 1 auto;min-height:46px;padding:.6rem 1rem;border:0;cursor:pointer;
  font:inherit;font-size:.88rem;font-weight:700;font-stretch:105%;letter-spacing:-.005em;
  background:var(--ink);color:var(--paper);transition:background-color .2s;
}
.consent__act button:hover{background:#2a2a27}
.consent__act button[data-consent="no"]{
  background:none;color:var(--ink);box-shadow:inset 0 0 0 1px rgba(0,0,0,.3);
}
.consent__act button[data-consent="no"]:hover{background:rgba(0,0,0,.06)}
.consent :focus-visible{outline:2px solid var(--ink);outline-offset:2px}
/* on a phone it spans the width, still sitting clear of the WhatsApp button */
@media (max-width:34rem){
  .consent{left:var(--wa-gap);right:var(--wa-gap);width:auto;bottom:calc(var(--wa-size) + (var(--wa-gap) * 2))}
}
@media (prefers-reduced-motion:reduce){
  .consent{transition:none}
  .consent[data-consent-state="in"]{transform:none}
}

/* ── touch and legibility on a phone ──────────────────────────────
   Measured at 390px rather than guessed at. The audience here is 40+ and
   arriving with reading glasses on, so this is a product requirement rather
   than a general nicety. */

/* Arrow links were 28px tall. That clears the WCAG minimum and still misses a
   thumb. The padding buys the target without moving the text: the negative
   margin puts the layout back where it was. */
.link{padding-block:.5rem;margin-block:-.5rem}

/* A price row heading that is also the link into that service was a 19px tap
   target, which is under the minimum, not merely tight. */
.price__row h3 a,.svc__row h3 a{display:inline-block;padding-block:.8rem;margin-block:-.8rem}

/* Form labels were 11.5px uppercase. On the one page where someone has to read
   carefully and type, that is the wrong place to be economical. */
.enq__lab{font-size:.82rem;letter-spacing:.14em}
.enq__err{font-size:.92rem}
