/* Care Home Website - base + section library v0.4
   Acorn & Oak Care Homes (Sep 2026). Cloned from the dual-home engine build, which
   carries the Elm round 6 gratwick-standard pass, the Gratwick component port, the
   the N-series build and dual-home engine rounds and the two-home rounds 1-7. Everything
   above the AO block at the foot of this file is shared library code; the AO block
   is this client's layer. The palette is entirely tokens.css: literal colours left
   in early library rules are overridden by token-driven rules further down (the
   last of them in AO.0). */

*{ box-sizing:border-box; margin:0; padding:0; }
html{ font-size:112.5%; scroll-behavior:smooth; -webkit-text-size-adjust:100%; }
body{ font-family:var(--body); color:var(--ink); background:var(--surface); line-height:1.6;
  -webkit-font-smoothing:antialiased; overflow-x:hidden; }
img{ display:block; max-width:100%; }
a{ color:var(--primary-ink); text-decoration:none; }
h1,h2,h3{ font-family:var(--display); font-weight:600; line-height:1.05; color:var(--ink); letter-spacing:-.015em; }
h1{ font-size:clamp(2.7rem,6vw,4.6rem); }
h2{ font-size:clamp(2rem,4vw,3.05rem); line-height:1.08; }
h3{ font-size:1.35rem; }
p{ font-size:1.04rem; }
.serif{ font-family:var(--display); font-style:italic; color:inherit; }

/* ---------- width helpers ---------- */
.full{ padding-inline:var(--w1); }
.w2{ padding-inline:var(--w2); }
.hold{ max-width:var(--hold); margin-inline:auto; padding-inline:var(--w1); }
.section{ padding-block:var(--sp); position:relative; }
.band-tint{ background:var(--band-tint); }
.band-accent{ background:var(--accent-tint); }
.band-deep{ background:var(--primary-deep); color:#fff; }
.band-deep h2,.band-deep h3{ color:#fff; }
.eyebrow{ font-size:.76rem; letter-spacing:.22em; text-transform:uppercase; font-weight:800; color:var(--primary-ink); }
.band-deep .eyebrow{ color:var(--accent-soft); }
.band-accent .eyebrow{ color:var(--cta-hover); }
.section-head{ max-width:40rem; }
.section-head.center{ max-width:46rem; margin-inline:auto; text-align:center; }
.section-head .say{ max-width:60ch; }
.section-head.center .say{ margin-inline:auto; }
.section-head h2{ margin-top:.7rem; }
.section-head .say{ margin-top:1rem; color:var(--ink-soft); font-size:1.12rem; }
.band-deep .section-head .say{ color:rgba(255,255,255,.8); }

/* ---------- buttons ---------- */
.btn{ display:inline-flex; align-items:center; justify-content:center; gap:.55rem; font-family:var(--body);
  font-weight:800; font-size:1rem; padding:1rem 1.7rem; border-radius:999px; background:var(--cta); color:#fff;
  border:2px solid var(--cta); cursor:pointer; transition:background .25s var(--ease), transform .25s var(--ease), border-color .25s; }
.btn:hover{ background:var(--cta-hover); border-color:var(--cta-hover); transform:translateY(-2px); }
.btn.light{ background:#fff; color:var(--primary-ink); border-color:#fff; }
.btn.light:hover{ background:#fff; transform:translateY(-2px); }
.btn.ghost-light{ background:transparent; color:#fff; border-color:rgba(255,255,255,.6); }
.btn.ghost-light:hover{ background:rgba(255,255,255,.12); border-color:#fff; }
.btn.ghost{ background:transparent; color:var(--primary-ink); border-color:var(--rule); }
.btn.ghost:hover{ background:#fff; border-color:var(--primary-ink); }
.tel-lg{ font-family:var(--display); font-weight:600; font-size:clamp(1.5rem,2.6vw,2rem); color:inherit; letter-spacing:-.01em; }
/* Base row for any pair of buttons. Every .cta-row used to depend on a parent
   (.hero, .cta, .hs-copy) supplying display:flex, so a row placed in a plain
   .section fell back to inline-block and ignored its own justify-content.
   Bug found on both home pages, 13 Aug 2026. Keep this rule first, the
   parent-scoped ones below still win on gap and alignment. */
.cta-row{ display:flex; gap:1rem; flex-wrap:wrap; align-items:center; }

/* ---------- reveal ---------- */
html.reveal-ready .reveal{ opacity:0; transform:translateY(26px); transition:opacity .8s var(--ease), transform .8s var(--ease); }
html.reveal-ready .reveal.in, .reveal.in{ opacity:1; transform:none; }
.reveal.d1{ transition-delay:.1s } .reveal.d2{ transition-delay:.2s } .reveal.d3{ transition-delay:.3s }
@media (prefers-reduced-motion: reduce){ .reveal{ opacity:1; transform:none; transition:none } html{ scroll-behavior:auto } }
.no-js .reveal{ opacity:1; transform:none; }

/* ---------- placeholders ---------- */
.ph{ position:relative; background-color:var(--band-tint);
  background-image:linear-gradient(135deg, var(--band-tint), var(--accent-tint)); display:grid; place-items:center;
  overflow:hidden; }
.ph::before{ content:attr(data-label); font-size:.82rem; font-weight:700; color:var(--primary-ink); opacity:.62;
  text-align:center; padding:1rem; max-width:26ch; }

/* ---------- nav (transparent over hero -> solid on scroll) ---------- */
.nav{ position:fixed; top:0; left:0; right:0; z-index:100; transition:background .3s var(--ease), box-shadow .3s, border-color .3s; border-bottom:1px solid transparent; }
.nav .bar{ display:flex; align-items:center; justify-content:space-between; gap:1.5rem; padding-block:1.15rem; padding-inline:var(--w1); }
.brand{ display:flex; align-items:center; gap:.6rem; font-family:var(--display); font-weight:600; font-size:1.4rem; color:#fff; transition:color .3s; }
.brand .mark{ width:34px; height:34px; border-radius:9px; background:var(--primary); display:grid; place-items:center; color:#fff; font-family:var(--body); font-weight:800; }
.navlinks{ display:flex; align-items:center; gap:2rem; }
/* R6: the links are truly centred on wide screens. The bar is flex
   space-between, and the phone + button side outweighs the brand, which
   used to drag the links about 80px left of the hero text's centre line. */
/* Absolute-centre the links only where the bar is wide enough to hold the full
   home name beside them. Below 1300 they flow naturally between the brand and
   the actions, which is the only way both fit; centring there would drive them
   straight through the wordmark. */
@media (min-width:1300px){
  .nav .bar{ position:relative; }
  .navlinks{ position:absolute; left:50%; transform:translateX(-50%); }
}
/* R6.8: the full home name shows at EVERY width. It used to appear only at
   1420px+, so on a 1366 or 1440 laptop the brand read its first word alone and
   the site looked inconsistent from one window size to the next. Instead of
   dropping the name, the bar tightens: between roughly 1040 and 1400 the
   wordmark and the links step down a little so the centred links still clear
   the brand and the actions. Centring is untouched. */
.wm-full{ display:inline; }
@media (min-width:1041px) and (max-width:1200px){
  .brand .wm{ font-size:1.04rem; }
  .brand .bird{ width:28px; height:21px; }
  .navlinks{ gap:.95rem; }
  .navlinks a:not(.btn){ font-size:.88rem; }
  .nav-tel{ font-size:.9rem; }
  .nav-actions .btn{ padding:.72rem 1.1rem; font-size:.88rem; }
}
@media (min-width:1201px) and (max-width:1400px){
  .brand .wm{ font-size:1.15rem; }
  .navlinks{ gap:1.15rem; }
  .navlinks a:not(.btn){ font-size:.92rem; }
  .nav-tel{ font-size:.95rem; }
}
@media (min-width:1401px) and (max-width:1560px){
  .navlinks{ gap:1.3rem; }
  .navlinks a:not(.btn){ font-size:.95rem; }
}
@media (max-width:430px){ .brand .wm{ font-size:1.02rem; } }
.navlinks a:not(.btn){ font-weight:700; font-size:1rem; color:rgba(255,255,255,.92); white-space:nowrap; transition:color .3s; }
.navlinks a:not(.btn):hover{ color:#fff; }
.nav-actions{ display:flex; align-items:center; gap:1.4rem; }
.nav-tel{ font-weight:800; color:#fff; white-space:nowrap; transition:color .3s; }
.burger{ display:none; width:46px; height:46px; border:1px solid rgba(255,255,255,.4); border-radius:12px; background:rgba(255,255,255,.08); cursor:pointer; }
.burger span{ display:block; width:20px; height:2px; background:#fff; margin:4px auto; border-radius:2px; transition:background .3s; }
.mobile-menu{ display:none; }
/* scrolled state */
.nav.scrolled{ background:rgba(251,248,240,.94); backdrop-filter:saturate(1.1) blur(10px); border-bottom-color:var(--rule); box-shadow:0 10px 30px -24px rgba(24,47,39,.4); }
.nav.scrolled .bar{ padding-block:.85rem; }
.nav.scrolled .brand{ color:var(--primary-ink); }
.nav.scrolled .navlinks a:not(.btn),.nav.scrolled .nav-tel{ color:var(--ink); }
.nav.scrolled .navlinks a:not(.btn):hover{ color:var(--primary-ink); }
.nav.scrolled .burger{ border-color:var(--rule); background:#fff; }
.nav.scrolled .burger span{ background:var(--ink); }

/* ---------- hero (full-bleed) ---------- */
.hero{ position:relative; min-height:92vh; display:grid; align-items:center; }
.hero .bg{ position:absolute; inset:0; }
.hero .bg .ph{ width:100%; height:100%; }
.hero .bg::after{ content:""; position:absolute; inset:0; background:var(--scrim); }
.hero .inner{ position:relative; z-index:2; text-align:center; max-width:60rem; margin-inline:auto; padding-inline:var(--w1); color:#fff; padding-top:5rem; }
.hero .eyebrow{ color:rgba(255,255,255,.85); }
.hero h1{ color:#fff; margin-top:1rem; text-shadow:0 2px 30px rgba(0,0,0,.25); }
.hero h1 .serif{ color:var(--accent-on-photo); }
.hero .sub{ color:rgba(255,255,255,.92); font-size:clamp(1.1rem,1.8vw,1.3rem); margin-top:1.3rem; max-width:44ch; margin-inline:auto; }
.hero .cta-row{ margin-top:2.2rem; display:flex; gap:1rem; justify-content:center; flex-wrap:wrap; }
.hero .scroll-cue{ position:absolute; bottom:2rem; left:50%; transform:translateX(-50%); z-index:2; color:rgba(255,255,255,.8); font-size:.78rem; letter-spacing:.2em; text-transform:uppercase; font-weight:700; }

/* ---------- values triple (premium) ---------- */
.values-grid{ margin-top:2.6rem; display:grid; grid-template-columns:repeat(3,1fr); gap:1.6rem; }
.value{ background:var(--card); border:1px solid var(--rule); border-radius:var(--radius); padding:2.4rem 2rem;
  box-shadow:var(--shadow-sm); text-align:center; position:relative; overflow:hidden; }
.value::before{ content:""; position:absolute; top:0; left:0; right:0; height:4px; background:var(--primary); opacity:.85; }
.value .ico{ width:58px; height:58px; margin:0 auto 1.2rem; border-radius:50%; background:var(--band-tint); display:grid; place-items:center; color:var(--primary-ink); }
.value h3{ font-size:1.4rem; }
.value p{ margin-top:.7rem; color:var(--ink-soft); font-size:1rem; }

/* ---------- homes (hover-reveal cards) ---------- */
.homes-grid{ margin-top:2.6rem; display:grid; grid-template-columns:repeat(3,1fr); gap:1.4rem; }
.home-card{ position:relative; aspect-ratio:3/4; border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow-sm);
  cursor:pointer; }
.home-card .home-img{ position:absolute; inset:0; }
.home-card .home-img.ph::before{ color:#fff; opacity:.85; }
.home-card .scrim{ position:absolute; inset:0; background:linear-gradient(180deg, rgba(24,47,39,0) 38%, rgba(24,47,39,.78) 100%); transition:background .6s var(--ease); }
.home-card .label{ position:absolute; left:0; right:0; bottom:0; padding:1.6rem; z-index:2; color:#fff; }
.home-card .label .place{ font-size:.76rem; letter-spacing:.16em; text-transform:uppercase; font-weight:800; color:var(--accent-soft); }
.home-card .label h3{ color:#fff; font-size:1.7rem; margin-top:.2rem; }
.home-card .label .more{ max-height:0; opacity:0; overflow:hidden; margin-top:0;
  transition:max-height .6s var(--ease), opacity .55s var(--ease), margin-top .6s var(--ease); }
.home-card .label .more p{ font-size:.98rem; color:rgba(255,255,255,.92); }
.home-card .label .more .view{ display:inline-flex; margin-top:1rem; font-weight:800; color:#fff; border:2px solid rgba(255,255,255,.6);
  padding:.55rem 1.1rem; border-radius:999px; font-size:.9rem; transition:background .25s, border-color .25s; }
.home-card:hover .scrim{ background:linear-gradient(180deg, rgba(24,47,39,.15) 0%, rgba(24,47,39,.88) 100%); }
.home-card:hover .label .more{ max-height:240px; opacity:1; margin-top:.9rem; }
.home-card:hover .label .more .view:hover{ background:rgba(255,255,255,.16); border-color:#fff; }

/* ---------- care (accent, distinct) ---------- */
.care-grid{ margin-top:2.6rem; display:grid; grid-template-columns:repeat(3,1fr); gap:1.4rem; }
.care-card{ background:var(--card); border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow-sm);
  border:1px solid var(--rule); display:flex; flex-direction:column; }
.care-card .care-photo{ aspect-ratio:3/2; }
.care-card .care-body{ padding:1.4rem 1.6rem 1.7rem; }
.care-card .tag{ font-size:.74rem; letter-spacing:.14em; text-transform:uppercase; font-weight:800; color:var(--cta); }
.care-card h3{ font-size:1.35rem; margin-top:.3rem; }
.care-card p{ margin-top:.55rem; color:var(--ink-soft); font-size:1rem; }
.care-foot{ margin:2.4rem auto 0; max-width:74ch; text-align:center; color:var(--ink-soft); text-wrap:balance; }
.care-foot a{ color:var(--cta-hover); font-weight:800; }

/* ---------- testimonials (carousel) ---------- */
.tcarousel{ position:relative; max-width:60rem; margin:2.4rem auto 0; text-align:center; }
.tstack{ display:grid; }
.tslide{ grid-area:1 / 1; opacity:0; visibility:hidden; transition:opacity .5s var(--ease); }
.tslide.active{ opacity:1; visibility:visible; }
.tstars{ color:var(--accent-soft); letter-spacing:.3em; font-size:1.1rem; }
.tquote{ font-family:var(--display); font-weight:500; font-style:italic; font-size:clamp(1.4rem,2.6vw,2rem);
  line-height:1.4; color:#fff; margin-top:1.2rem; }
.tattr{ margin-top:1.6rem; font-weight:800; color:#fff; letter-spacing:.02em; }
.tattr span{ display:block; font-weight:600; color:rgba(255,255,255,.7); font-size:.9rem; margin-top:.2rem; }
.tnav{ display:flex; gap:.6rem; justify-content:center; align-items:center; margin-top:2rem; }
.tdot{ width:9px; height:9px; border-radius:50%; background:rgba(255,255,255,.32); border:0; cursor:pointer; transition:background .3s, transform .3s; }
.tdot.active{ background:#fff; transform:scale(1.25); }
.tarrow{ width:46px; height:46px; border-radius:50%; border:1px solid rgba(255,255,255,.4); background:transparent; color:#fff; cursor:pointer; font-size:1.1rem; transition:background .25s; }
.tarrow:hover{ background:rgba(255,255,255,.14); }

/* ---------- funding (premium two-col) ---------- */
.funding-grid{ display:grid; grid-template-columns:1.05fr .95fr; gap:clamp(2rem,4vw,4rem); align-items:center; }
.funding-copy .lede{ margin-top:1rem; color:var(--ink-soft); font-size:1.1rem; max-width:46ch; }
.funding-copy .welcome{ display:inline-flex; align-items:center; gap:.5rem; margin-top:1.4rem; background:#fff;
  border:1px solid var(--rule); color:var(--primary-ink); font-weight:800; padding:.65rem 1.15rem; border-radius:999px; box-shadow:var(--shadow-sm); }
.fsteps{ margin-top:2rem; display:flex; flex-direction:column; gap:1.2rem; }
.fstep{ display:flex; gap:1.1rem; align-items:flex-start; }
.fstep .n{ flex:none; width:44px; height:44px; border-radius:50%; background:var(--primary-ink); color:#fff; display:grid; place-items:center; font-weight:800; }
.fstep h3{ font-family:var(--body); font-weight:800; font-size:1.1rem; }
.fstep p{ margin-top:.25rem; color:var(--ink-soft); font-size:1rem; }
.funding-photo{ border-radius:var(--radius); overflow:hidden; aspect-ratio:4/5; box-shadow:var(--shadow); min-height:360px; }

/* ---------- CTA (light, warm) ---------- */
.cta{ background:linear-gradient(160deg, var(--surface) 0%, var(--accent-tint) 100%); text-align:center; }
.cta h2{ max-width:20ch; margin-inline:auto; }
.cta p{ margin-top:.9rem; color:var(--ink-soft); font-size:1.12rem; }
.cta .cta-row{ margin-top:1.8rem; display:flex; gap:1.4rem; justify-content:center; align-items:center; flex-wrap:wrap; }
.cta .tel-lg{ color:var(--primary-ink); }

/* ---------- footer ---------- */
.foot{ background:var(--primary-deep); color:rgba(255,255,255,.86); }
.foot .cols{ display:grid; grid-template-columns:repeat(3,1fr) 1.2fr; gap:2.2rem; padding-block:3.6rem; padding-inline:var(--w2); }
.foot h4{ color:#fff; font-family:var(--body); font-weight:800; font-size:.82rem; letter-spacing:.14em; text-transform:uppercase; margin-bottom:.9rem; }
.foot a{ color:rgba(255,255,255,.86); display:block; margin-bottom:.4rem; }
/* Jon, 6 Sep 2026: footer links underline on hover. text-underline-offset keeps
   the rule clear of the descenders, and the colour lift is kept so the two
   signals arrive together. */
.foot a:hover{ color:#fff; text-decoration:underline; text-underline-offset:3px; }
.foot .fcol p{ color:rgba(255,255,255,.72); font-size:.95rem; }
.foot-legal{ border-top:1px solid rgba(255,255,255,.14); }
.foot-legal .row{ display:flex; justify-content:space-between; gap:1rem; flex-wrap:wrap; padding-block:1.3rem; padding-inline:var(--w2); font-size:.85rem; color:rgba(255,255,255,.66); }
.foot-legal a{ color:rgba(255,255,255,.8); display:inline; }
.credit a{ color:var(--accent-soft); font-weight:700; }

/* ---------- responsive ---------- */
@media (max-width:1000px){
  .values-grid,.homes-grid,.care-grid{ grid-template-columns:1fr 1fr; }
  .funding-grid{ grid-template-columns:1fr; }
  .funding-photo{ aspect-ratio:16/10; order:-1; }
  .foot .cols{ grid-template-columns:1fr 1fr; }
}
@media (max-width:760px){
  .navlinks{ display:none; }
  .nav-actions .nav-tel,.nav-actions .btn{ display:none; }
  .burger{ display:block; }
  .mobile-menu{ display:none; position:absolute; left:0; right:0; top:100%; background:var(--surface); border-bottom:1px solid var(--rule); box-shadow:var(--shadow-sm); padding:.6rem var(--w1) 1.4rem; }
  .mobile-menu.open{ display:flex; flex-direction:column; }
  .mobile-menu a{ padding:.9rem .2rem; font-weight:700; border-bottom:1px solid var(--rule); color:var(--ink); }
  .mobile-menu a.btn{ margin-top:1rem; border-bottom:none; color:#fff; justify-content:center; }
  .values-grid,.homes-grid,.care-grid{ grid-template-columns:1fr; }
  .home-card{ aspect-ratio:4/3; }
  .home-card .reveal-panel{ opacity:1; transform:none; } /* touch: always show */
  .home-card .scrim{ background:linear-gradient(180deg, rgba(24,47,39,.1) 30%, rgba(24,47,39,.85) 100%); }
  .foot .cols{ grid-template-columns:1fr 1fr; gap:1.6rem; }
  h1{ font-size:clamp(2.4rem,9vw,3.2rem); }
}
@media (max-width:430px){ .foot .cols{ grid-template-columns:1fr; } }

/* ============ INDIVIDUAL HOME PAGE ============ */
.hero.compact{ min-height:74vh; }
.hero .home-place{ display:inline-block; }

/* key-info bar under hero */
.keyinfo{ background:var(--card); border-bottom:1px solid var(--rule); }
.keyinfo .row{ display:flex; align-items:center; justify-content:center; gap:1.3rem; flex-wrap:wrap; padding-block:1.5rem; padding-inline:var(--w1); }
.ki-label{ font-size:.72rem; letter-spacing:.18em; text-transform:uppercase; font-weight:800; color:var(--ink-soft); }
.keyinfo .kchips{ display:flex; gap:.7rem; flex-wrap:wrap; justify-content:center; }
.kchip{ font-size:.82rem; font-weight:800; color:var(--primary-ink); background:var(--band-tint); padding:.5rem 1.05rem; border-radius:999px; }

/* about this home (image 8/9 layout) */
.about-grid{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(2rem,5vw,4.5rem); align-items:center; }
.script{ font-family:var(--display); font-style:italic; font-size:1.5rem; color:var(--cta); }
.about-copy h2{ margin-top:.2rem; text-transform:uppercase; letter-spacing:.06em; }
.about-copy .body{ margin-top:1.2rem; color:var(--ink-soft); font-size:1.08rem; max-width:48ch; }
.cs-title{ margin-top:2rem; font-size:.8rem; letter-spacing:.18em; text-transform:uppercase; font-weight:800; color:var(--ink); padding-bottom:.8rem; border-bottom:1px solid var(--rule); }
.cs-grid{ margin-top:1.1rem; display:grid; grid-template-columns:1fr 1fr; gap:.7rem; }
.cs-item{ display:flex; align-items:center; gap:.6rem; background:var(--surface); border:1px solid var(--rule); border-radius:12px; padding:.7rem 1rem; font-weight:700; color:var(--ink); font-size:.95rem; }
.cs-item .dot{ width:8px; height:8px; border-radius:50%; background:var(--cta); flex:none; }
.about-cta{ margin-top:1.9rem; display:flex; gap:1rem; align-items:center; flex-wrap:wrap; }
.about-cta .tel{ font-weight:800; color:var(--primary-ink); }
.framed-wrap{ position:relative; }
.framed-wrap::before{ content:""; position:absolute; inset:0; transform:translate(22px,22px); border:1.5px solid var(--cta); border-radius:var(--radius); z-index:0; opacity:.55; }
.framed{ position:relative; z-index:1; border-radius:var(--radius); overflow:hidden; aspect-ratio:4/5; box-shadow:var(--shadow); min-height:420px; }
.framed-wrap.sm .framed{ aspect-ratio:1/1; min-height:0; }
/* .wide: for a photograph of a BUILDING. The 4/5 default is built for interiors
   and people, where a portrait crop flatters; on a wide elevation it cuts both
   ends off the house and leaves a wall. 4/3 keeps about nine tenths of the
   frame's width, so the whole building reads. */
.framed-wrap.wide .framed{ aspect-ratio:4/3; min-height:0; }
@media (max-width:760px){ .framed-wrap::before{ transform:translate(12px,12px); } }

/* highlights */
.hl-grid{ margin-top:2.4rem; display:grid; grid-template-columns:repeat(3,1fr); gap:1.2rem; }
.hl{ background:var(--card); border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow-sm); border:1px solid var(--rule); }
.hl .hl-img{ aspect-ratio:3/2; }
.hl .hl-body{ padding:1.2rem 1.3rem 1.4rem; }
.hl h3{ font-size:1.2rem; }
.hl p{ margin-top:.4rem; color:var(--ink-soft); font-size:.96rem; }

/* feature duo (rooms) */
.feature-duo{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(2rem,4vw,3.6rem); align-items:center; }
.feature-duo.flip .fd-photo{ order:2; }
.fd-photo{ border-radius:var(--radius); overflow:hidden; aspect-ratio:4/3; box-shadow:var(--shadow-sm); min-height:320px; }
.fd-copy .body{ margin-top:1rem; color:var(--ink-soft); font-size:1.06rem; max-width:46ch; }
.amenities{ margin-top:1.4rem; display:flex; flex-wrap:wrap; gap:.6rem; }

/* life / activities band */
.act-band{ margin-top:2.4rem; display:grid; grid-template-columns:repeat(4,1fr); grid-auto-rows:200px; gap:1rem; }
.act-band .act{ border-radius:var(--radius-sm); overflow:hidden; }
.act-band .act.tall{ grid-row:span 2; }

/* location */
.loc-grid{ display:grid; grid-template-columns:1.3fr 1fr; gap:clamp(2rem,4vw,3.6rem); align-items:stretch; }
.loc-map{ border-radius:var(--radius); overflow:hidden; min-height:360px; }
.loc-details h3{ font-size:1.35rem; }
.loc-details .li{ margin-top:1.1rem; }
.loc-details .li b{ display:block; font-family:var(--body); font-weight:800; color:var(--ink); font-size:.95rem; }
.loc-details .li span{ color:var(--ink-soft); }

/* cqc at bottom (honest, neutral) */
.cqc-card{ display:flex; align-items:center; justify-content:space-between; gap:1.4rem; flex-wrap:wrap; background:var(--card); border:1px solid var(--rule); border-radius:var(--radius); padding:1.6rem 2rem; box-shadow:var(--shadow-sm); }
.cqc-card .cqc-txt b{ font-family:var(--body); font-weight:800; }
.cqc-card .cqc-txt p{ color:var(--ink-soft); margin-top:.3rem; font-size:.96rem; }

/* back to homes */
.svc-return{ text-align:center; padding-block:2.4rem; }
.svc-return a{ font-weight:800; color:var(--primary-ink); border:1px solid var(--rule); border-radius:999px; padding:.65rem 1.4rem; display:inline-block; }
.svc-return a:hover{ background:var(--band-tint); }

@media (max-width:1000px){
  .about-grid,.feature-duo,.loc-grid{ grid-template-columns:1fr; }
  .feature-duo.flip .fd-photo{ order:-1; }
  .framed{ aspect-ratio:16/11; order:-1; }
  .hl-grid{ grid-template-columns:1fr 1fr; }
  .act-band{ grid-template-columns:repeat(2,1fr); grid-auto-rows:170px; }
  .act-band .act.tall{ grid-row:span 1; }
}
@media (max-width:760px){
  .hl-grid,.cs-grid{ grid-template-columns:1fr; }
  .keyinfo .row{ gap:.8rem; }
}

/* ============ OUR CARE PAGE ============ */
.approach-copy h2{ margin-top:.4rem; }
.approach-copy .body{ margin-top:1.1rem; color:var(--ink-soft); font-size:1.08rem; max-width:48ch; }
.approach-copy .body + .body{ margin-top:1rem; }

/* care accordion + swapping photo */
.care-accordion{ display:grid; grid-template-columns:.82fr 1.18fr; gap:clamp(2rem,4vw,4rem); align-items:start; margin-top:2.4rem; }
.ca-photo{ position:sticky; top:110px; border-radius:var(--radius); overflow:hidden; aspect-ratio:1/1; box-shadow:var(--shadow); }
.ca-photo .ca-img{ position:absolute; inset:0; opacity:0; transition:opacity .5s var(--ease); }
.ca-photo .ca-img.active{ opacity:1; }
.acc{ display:flex; flex-direction:column; }
.acc-item{ border-bottom:1px solid var(--rule); }
.acc-item:first-child{ border-top:1px solid var(--rule); }
.acc-head{ width:100%; text-align:left; background:none; border:0; cursor:pointer; display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:1.35rem 0; font-family:var(--display); font-weight:600; font-size:1.32rem; color:var(--ink); }
.acc-head .pm{ position:relative; width:22px; height:22px; flex:none; }
.acc-head .pm::before,.acc-head .pm::after{ content:""; position:absolute; background:var(--cta); border-radius:2px; transition:transform .3s var(--ease); }
.acc-head .pm::before{ left:0; right:0; top:50%; height:2px; transform:translateY(-50%); }
.acc-head .pm::after{ top:0; bottom:0; left:50%; width:2px; transform:translateX(-50%); }
.acc-item.open .acc-head .pm::after{ transform:translateX(-50%) scaleY(0); }
.acc-body{ overflow:hidden; max-height:0; transition:max-height .4s var(--ease); }
.acc-body-inner{ padding-bottom:1.5rem; color:var(--ink-soft); font-size:1.05rem; max-width:52ch; }
.acc-body-inner .avail{ margin-top:.9rem; font-size:.82rem; font-weight:800; letter-spacing:.02em; color:var(--primary-ink); }

/* day timeline */
.timeline{ margin-top:2.6rem; display:grid; gap:0; max-width:720px; margin-inline:auto; }
.tl-item{ display:grid; grid-template-columns:auto 1fr; gap:1.4rem; align-items:start; position:relative; padding-bottom:1.8rem; }
.tl-num{ width:54px; height:54px; border-radius:50%; background:var(--primary-ink); color:#fff; display:grid; place-items:center; font-weight:800; font-family:var(--body); flex:none; z-index:1; }
.tl-item::before{ content:""; position:absolute; left:27px; top:54px; bottom:0; width:2px; background:var(--rule); }
.tl-item:last-child{ padding-bottom:0; }
.tl-item:last-child::before{ display:none; }
.tl-body{ padding-top:.5rem; }
.tl-body h3{ font-family:var(--body); font-weight:800; font-size:1.2rem; }
.tl-body p{ margin-top:.3rem; color:var(--ink-soft); }

/* funding mini (condensed) */
.fund-mini{ text-align:center; }
.fund-mini .welcome{ display:inline-flex; align-items:center; gap:.5rem; margin-top:1.2rem; background:#fff; border:1px solid var(--rule); color:var(--primary-ink); font-weight:800; padding:.65rem 1.15rem; border-radius:999px; box-shadow:var(--shadow-sm); }
.fund-mini .flink{ display:block; margin-top:1.4rem; font-weight:800; color:var(--cta-hover); }

/* faq */
.faq{ max-width:820px; margin:2.4rem auto 0; }
.faq .acc-head{ font-family:var(--body); font-weight:800; font-size:1.12rem; padding:1.2rem 0; }
.faq .acc-body-inner{ max-width:none; }

@media (max-width:900px){
  .care-accordion{ grid-template-columns:1fr; }
  .ca-photo{ position:relative; top:0; aspect-ratio:16/10; min-height:0; order:-1; }
}

/* ============ REAL IMAGES ============ */
.cover{ display:block; width:100%; height:100%; object-fit:cover; }
.brand-logo{ height:42px; width:auto; display:block; filter:drop-shadow(0 2px 10px rgba(0,0,0,.45)); transition:filter .3s var(--ease); }
.nav.scrolled .brand-logo{ filter:none; }
.hero .bg img.cover{ position:absolute; inset:0; object-position:center 32%; }
/* page transition REMOVED (round 6). This rule hid the entire site behind
   body{opacity:0} and depended on script.js adding .loaded; a blocked or
   failed script.js rendered every page blank. Replaced by the .veil element,
   which a CSS animation always clears. See ROUND 6 section 6.5. */
/* two-up gallery variant (for pages with just a couple of life photos) */
.act-band.pair{ grid-template-columns:1fr 1fr; grid-auto-rows:auto; }
.act-band.pair .act{ aspect-ratio:3/2; }
@media (max-width:760px){ .act-band.pair{ grid-template-columns:1fr; } }

/* ============ CONTACT PAGE ============ */
.contact-wrap{ max-width:1560px; margin-inline:auto; padding-inline:var(--w1); }
.contact-wrap .section-head{ margin-bottom:.6rem; }
.contact-grid{ display:grid; grid-template-columns:1.6fr .9fr; gap:clamp(2.4rem,4.5vw,5rem); align-items:start; margin-top:2.6rem; }
.enquiry{ background:var(--card); border-radius:var(--radius); padding:clamp(1.8rem,3.2vw,3.2rem); box-shadow:var(--shadow); }
.step-label{ font-family:var(--body); font-weight:800; color:var(--ink); font-size:1.05rem; margin-bottom:.3rem; display:flex; align-items:center; gap:.6rem; }
.step-label .step-n{ width:26px; height:26px; border-radius:50%; background:var(--primary-ink); color:#fff; font-size:.85rem; display:grid; place-items:center; flex:none; }
.step-hint{ color:var(--ink-soft); font-size:.92rem; margin:.15rem 0 1rem 2.15rem; }
.home-select{ display:grid; grid-template-columns:repeat(3,1fr); gap:1rem; margin-bottom:1.9rem; }
.home-opt{ position:relative; }
.home-opt input{ position:absolute; inset:0; opacity:0; cursor:pointer; margin:0; }
.home-opt label{ display:block; height:100%; cursor:pointer; border:2px solid var(--rule); border-radius:14px; padding:1.15rem 1.1rem 1.25rem; background:var(--surface); transition:border-color .2s var(--ease), background .2s var(--ease), box-shadow .2s var(--ease), transform .2s var(--ease); }
.home-opt .place{ font-size:.66rem; letter-spacing:.16em; text-transform:uppercase; font-weight:800; color:var(--ink-soft); display:block; }
.home-opt .hn{ font-family:var(--display); font-size:1.14rem; color:var(--ink); margin-top:.2rem; display:block; line-height:1.15; }
.home-opt .tick{ position:absolute; top:.7rem; right:.7rem; width:22px; height:22px; border-radius:50%; border:2px solid var(--rule); background:#fff; display:grid; place-items:center; transition:.2s var(--ease); }
.home-opt .tick svg{ opacity:0; transition:opacity .2s; }
.home-opt input:hover + label{ border-color:var(--primary); }
.home-opt input:checked + label{ border-color:var(--cta); background:var(--accent-tint); box-shadow:0 8px 22px rgba(185,138,46,.24); transform:translateY(-2px); }
.home-opt input:checked + label .tick{ background:var(--cta); border-color:var(--cta); }
.home-opt input:checked + label .tick svg{ opacity:1; }
.home-opt input:focus-visible + label{ outline:2px solid var(--primary-ink); outline-offset:2px; }
.enq-banner{ display:flex; align-items:center; gap:.7rem; background:var(--band-tint); border:1px solid var(--rule); border-radius:12px; padding:.85rem 1.1rem; font-family:var(--body); font-weight:700; color:var(--primary-deep); margin-bottom:1.6rem; font-size:.98rem; }
.enq-banner svg{ flex:none; color:var(--primary-ink); }
.enq-banner b{ color:var(--cta-hover); }
.field{ margin-bottom:1.25rem; }
.field-row + .field, .field-row + .field-row{ margin-top:0; }
.enq-banner + .step-label{ margin-top:.3rem; }
.field > label{ display:block; font-family:var(--body); font-weight:700; font-size:.9rem; color:var(--ink); margin-bottom:.4rem; }
.field .opt{ color:var(--ink-soft); font-weight:600; }
.field input, .field select, .field textarea{ width:100%; font-family:var(--body); font-size:1rem; color:var(--ink); background:var(--surface); border:1.5px solid var(--rule); border-radius:10px; padding:.8rem .9rem; transition:border-color .2s var(--ease), box-shadow .2s var(--ease); }
.field input:focus, .field select:focus, .field textarea:focus{ outline:none; border-color:var(--primary-ink); box-shadow:0 0 0 3px var(--focus-ring); }
/* The focus ring on a form field used to be rgba(--shadow-rgb,.20), a 20% warm
   grey halo, which on a light field is close to invisible: keyboard users could
   not tell which box they were in. It is now a token, set to the brand accent at
   a strength that actually reads, and the border deepens to the accent ink at
   the same time so there are two signals rather than one faint one. Older, less
   dexterous visitors are the audience here, so this is conversion, not
   compliance. PROMOTE UPSTREAM: every build in the library shipped the faint
   version. */
.field textarea{ min-height:120px; resize:vertical; }
.field-row{ display:grid; grid-template-columns:1fr 1fr; gap:1.4rem; }
.consent{ display:flex; gap:.65rem; align-items:flex-start; font-size:.86rem; color:var(--ink-soft); margin:.4rem 0 1.3rem; line-height:1.5; }
.consent input{ width:auto; margin-top:.15rem; flex:none; }
.consent a{ color:var(--primary-ink); font-weight:700; text-decoration:underline; }
.enq-submit{ width:100%; justify-content:center; }
.enq-success{ display:none; text-align:center; padding:1.5rem .5rem; }
.enq-success.show{ display:block; }
.enq-success .es-ico{ width:64px; height:64px; border-radius:50%; background:var(--band-tint); color:var(--primary-ink); display:grid; place-items:center; margin:0 auto 1.1rem; }
.enq-success h3{ font-size:1.5rem; }
.enq-success p{ color:var(--ink-soft); margin-top:.6rem; max-width:42ch; margin-inline:auto; }
.enq-success .sh-home{ color:var(--cta-hover); font-weight:800; }
/* aside: prefer to talk */
.contact-aside{ position:sticky; top:110px; }
.contact-aside > h3{ font-size:1.35rem; margin-bottom:.4rem; }
.contact-aside > p{ color:var(--ink-soft); margin-bottom:1.4rem; }
.cblock{ background:var(--card); border:1px solid var(--rule); border-radius:var(--radius-sm); padding:1.2rem 1.3rem; box-shadow:var(--shadow-sm); }
.cblock + .cblock{ margin-top:.9rem; }
.cblock h4{ font-family:var(--display); font-weight:600; font-size:1.18rem; color:var(--ink); }
.cblock .place{ font-size:.66rem; letter-spacing:.16em; text-transform:uppercase; font-weight:800; color:var(--ink-soft); display:block; margin-bottom:.15rem; }
.cblock .crow{ display:flex; align-items:flex-start; gap:.6rem; margin-top:.8rem; color:var(--ink-soft); font-size:.95rem; }
.cblock .crow svg{ flex:none; color:var(--primary-ink); margin-top:.15rem; }
.cblock .crow a{ color:var(--ink); font-weight:700; }
.cblock .crow a:hover{ color:var(--primary-ink); }
.aside-note{ margin-top:1.2rem; background:var(--band-tint); border-radius:var(--radius-sm); padding:1.1rem 1.3rem; color:var(--primary-deep); font-size:.95rem; }
.aside-note b{ font-family:var(--body); }
@media (max-width:1000px){
  .contact-grid{ grid-template-columns:1fr; }
  .contact-aside{ position:static; }
}
@media (max-width:620px){
  .home-select{ grid-template-columns:1fr; }
  .field-row{ grid-template-columns:1fr; gap:0; }
}

/* ============================================================
   ELM PRESET ADDITIONS (preset 3 "Elm", single-home, Homely)
   New sections + palette-neutral overrides of teal hardcodes.
   PROMOTE these upstream into the canonical Vitality base.css
   so future clones inherit them (see BUILD_NOTES).
   ============================================================ */

/* --- neutralise teal-specific hardcodes from v0.2 --- */
.band-deep .eyebrow{ color:var(--accent-soft); }
.credit a{ color:var(--accent-soft); }
.field input:focus, .field select:focus, .field textarea:focus{ box-shadow:0 0 0 3px var(--focus-ring); }
.nav.scrolled{ box-shadow:0 10px 30px -24px rgba(24,47,39,.45); }
.hero h1 .serif{ color:var(--accent-on-photo); }

/* --- nav: solid from the top (used on the light split-hero home page) --- */
.nav.solid{ background:rgba(251,248,240,.94); backdrop-filter:saturate(1.1) blur(10px);
  border-bottom-color:var(--rule); box-shadow:0 10px 30px -24px rgba(24,47,39,.4); }
.nav.solid .brand{ color:var(--primary-ink); }
.nav.solid .navlinks a:not(.btn), .nav.solid .nav-tel{ color:var(--ink); }
.nav.solid .navlinks a:not(.btn):hover{ color:var(--primary-ink); }
.nav.solid .burger{ border-color:var(--rule); background:#fff; }
.nav.solid .burger span{ background:var(--ink); }

/* --- brand wordmark + elm-leaf mark (inline SVG, currentColor) --- */
.brand{ gap:.55rem; }
.brand .leaf{ width:30px; height:30px; flex:none; color:var(--primary); display:block; }
.nav:not(.scrolled):not(.solid) .brand .leaf{ color:#fff; filter:drop-shadow(0 2px 8px rgba(0,0,0,.4)); }
.brand .wm{ font-family:var(--display); font-weight:600; letter-spacing:.005em; line-height:1; }

/* --- SPLIT-COLLAGE HERO (D1, light background) --- */
.hero-split{ position:relative; padding-top:clamp(7rem,12vh,9.5rem); padding-bottom:var(--sp);
  background:linear-gradient(180deg, var(--band-tint) 0%, var(--surface) 78%); overflow:hidden; }
.hs-grid{ display:grid; grid-template-columns:1.02fr .98fr; gap:clamp(2rem,5vw,4.5rem); align-items:center; }
.hs-copy .eyebrow{ color:var(--primary-ink); }
.hs-copy h1{ margin-top:1rem; }
.hs-copy h1 .serif{ color:var(--cta); }
.hs-copy .sub{ margin-top:1.3rem; color:var(--ink-soft); font-size:clamp(1.1rem,1.7vw,1.28rem); max-width:42ch; }
.hs-copy .cta-row{ margin-top:2rem; display:flex; gap:1rem; flex-wrap:wrap; }
.hs-trust{ margin-top:1.9rem; display:flex; align-items:center; gap:.7rem; color:var(--ink-soft); font-size:.96rem; }
.hs-trust .cqc-dot{ flex:none; width:38px; height:38px; border-radius:50%; background:var(--band-tint);
  border:1px solid var(--rule); display:grid; place-items:center; color:var(--primary-ink); }
.hs-trust b{ color:var(--ink); font-family:var(--body); font-weight:800; }
.hs-collage{ position:relative; min-height:clamp(360px,52vw,540px); }
.hs-ph{ position:absolute; border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow); }
.hs-ph.a{ inset:0 22% 26% 0; }
.hs-ph.b{ width:52%; right:0; bottom:0; aspect-ratio:4/5; border:6px solid var(--surface); }
.hs-ph .ph, .hs-ph img.cover{ width:100%; height:100%; }
.hs-badge{ position:absolute; left:-8px; bottom:16%; z-index:3; background:var(--card); border:1px solid var(--rule);
  border-radius:14px; box-shadow:var(--shadow-sm); padding:.7rem 1rem; display:flex; align-items:center; gap:.6rem;
  font-weight:800; color:var(--primary-ink); font-size:.92rem; }
.hs-badge .n{ font-family:var(--display); font-size:1.5rem; color:var(--cta); line-height:1; }

/* --- STATS STRIP (D2 first section) --- */
.stats-strip{ display:grid; grid-template-columns:repeat(4,1fr); gap:1.1rem; }
.stat{ background:var(--card); border:1px solid var(--rule); border-radius:var(--radius-sm);
  box-shadow:var(--shadow-sm); padding:1.5rem 1.4rem; text-align:left; position:relative; }
.stat::before{ content:""; position:absolute; left:1.4rem; top:0; width:34px; height:3px; background:var(--primary); border-radius:0 0 3px 3px; }
.stat .big{ font-family:var(--display); font-weight:600; font-size:clamp(1.6rem,2.4vw,2.1rem); color:var(--ink); line-height:1.05; }
.stat .lab{ margin-top:.4rem; color:var(--ink-soft); font-size:.96rem; }
.stat a.big-link{ color:inherit; }

/* --- EDITORIAL BEAT (mid-page emotional moment) --- */
.beat{ text-align:center; }
.beat .kicker{ color:var(--cta); font-weight:800; letter-spacing:.14em; text-transform:uppercase; font-size:.78rem; }
.beat blockquote{ font-family:var(--display); font-weight:500; font-style:italic;
  font-size:clamp(1.55rem,3.2vw,2.5rem); line-height:1.32; color:var(--ink); max-width:22ch;
  margin:1.1rem auto 0; }
.beat blockquote b{ font-style:normal; font-weight:600; color:var(--primary-ink); }
.beat .by{ margin-top:1.4rem; color:var(--ink-soft); font-size:1rem; }

/* --- simple photo-strip (life) --- */
.strip3{ margin-top:2.4rem; display:grid; grid-template-columns:repeat(3,1fr); gap:1rem; }
.strip3 .s{ border-radius:var(--radius-sm); overflow:hidden; aspect-ratio:3/4; }
.strip3 .s.wide{ aspect-ratio:3/4; }

/* --- horizontal steps (arranging a visit) --- */
.steps-row{ margin-top:2.4rem; display:grid; grid-template-columns:repeat(4,1fr); gap:1.2rem; counter-reset:step; }
.steps-row .st{ position:relative; padding-top:.4rem; }
.steps-row .st .n{ width:44px; height:44px; border-radius:50%; background:var(--primary-ink); color:#fff;
  display:grid; place-items:center; font-weight:800; margin-bottom:.9rem; }
.steps-row .st h3{ font-family:var(--body); font-weight:800; font-size:1.08rem; }
.steps-row .st p{ margin-top:.3rem; color:var(--ink-soft); font-size:.98rem; }

/* --- fade-scale reveal (D7 for this preset) --- */
.reveal.scale{ transform:translateY(20px) scale(.975); }
.reveal.scale.in{ transform:none; }

/* --- CQC honest chip, richer (about page + trust band) --- */
.cqc-chip{ display:flex; align-items:center; gap:1.1rem; flex-wrap:wrap; background:var(--card);
  border:1px solid var(--rule); border-radius:var(--radius); padding:1.5rem 1.8rem; box-shadow:var(--shadow-sm); }
.cqc-chip .seal{ flex:none; width:60px; height:60px; border-radius:50%; background:var(--band-tint);
  border:1px solid var(--rule); display:grid; place-items:center; color:var(--primary-ink); }
.cqc-chip .ct{ flex:1; min-width:220px; }
.cqc-chip .ct b{ font-family:var(--body); font-weight:800; color:var(--ink); font-size:1.08rem; }
.cqc-chip .ct p{ color:var(--ink-soft); margin-top:.3rem; font-size:.95rem; }
.band-deep .cqc-chip{ background:rgba(255,255,255,.06); border-color:rgba(255,255,255,.18); }
.band-deep .cqc-chip .seal{ background:rgba(255,255,255,.1); border-color:rgba(255,255,255,.2); color:#fff; }
.band-deep .cqc-chip .ct b{ color:#fff; }
.band-deep .cqc-chip .ct p{ color:rgba(255,255,255,.8); }

/* --- cookie notice --- */
.cookie{ position:fixed; left:1rem; right:1rem; bottom:1rem; z-index:200; max-width:640px; margin-inline:auto;
  background:var(--primary-deep); color:rgba(255,255,255,.9); border-radius:14px; box-shadow:var(--shadow);
  padding:1rem 1.2rem; display:flex; align-items:center; gap:1rem; font-size:.92rem; }
.cookie.hide{ display:none; }
.cookie p{ font-size:.92rem; }
.cookie a{ color:var(--accent-soft); text-decoration:underline; }
.cookie button{ flex:none; font-family:var(--body); font-weight:800; font-size:.9rem; border:0; cursor:pointer;
  background:#fff; color:var(--primary-deep); border-radius:999px; padding:.55rem 1.1rem; }

/* --- prose (privacy page) --- */
.prose{ max-width:70ch; }
.prose h2{ font-size:1.5rem; margin-top:2.2rem; }
.prose h3{ margin-top:1.6rem; }
.prose p, .prose li{ color:var(--ink-soft); font-size:1.02rem; margin-top:.8rem; }
.prose ul{ margin-top:.6rem; padding-left:1.2rem; }
.prose a{ color:var(--primary-ink); font-weight:700; text-decoration:underline; }

/* --- Elm responsive --- */
@media (max-width:1000px){
  .hs-grid{ grid-template-columns:1fr; gap:2.4rem; }
  .hs-collage{ min-height:clamp(320px,80vw,460px); order:-1; }
  .stats-strip{ grid-template-columns:1fr 1fr; }
  .steps-row{ grid-template-columns:1fr 1fr; }
}
@media (max-width:600px){
  .stats-strip{ grid-template-columns:1fr 1fr; }
  .strip3{ grid-template-columns:1fr; }
  .steps-row{ grid-template-columns:1fr; }
  .hs-ph.a{ inset:0 26% 30% 0; }
}

/* --- Elm small utilities --- */
.care-grid.c4{ grid-template-columns:repeat(4,1fr); }
.foot .fmuted{ color:rgba(255,255,255,.6); display:block; margin-bottom:.4rem; }
.about-copy .body + .body{ margin-top:1rem; }
.lede-list{ margin-top:1.3rem; display:flex; flex-direction:column; gap:.7rem; }
.lede-list .li2{ display:flex; gap:.7rem; align-items:flex-start; color:var(--ink-soft); font-size:1.02rem; }
.lede-list .li2 svg{ flex:none; color:var(--primary-ink); margin-top:.25rem; }
@media (max-width:1000px){ .care-grid.c4{ grid-template-columns:1fr 1fr; } }
@media (max-width:600px){ .care-grid.c4{ grid-template-columns:1fr; } }

/* --- Elm fix: release fixed photo min-heights on small screens so
   aspect-ratio drives width (prevents min-width overflow at <=1000/390) --- */
@media (max-width:1000px){
  .framed{ min-height:0; }
  .framed-wrap.sm .framed{ min-height:0; }
  .funding-photo{ min-height:0; }
  .fd-photo{ min-height:0; }
  .loc-map{ min-height:0; }
}

/* --- Elm: keep hero placeholders clean (hide slot label behind hero titles) --- */
.hero .bg .ph::before{ display:none; }

/* ============================================================
   ELM ROUND 2 - premium polish + consistency fixes
   (promote upstream to Vitality base.css)
   ============================================================ */

/* C1+C3 - placeholders always fill their slot AND show a neat, uniform
   bottom label strip (fixes the trim showing through + mismatched "banners") */
.ph{ position:relative; width:100%; height:100%; }
.framed, .fd-photo, .funding-photo, .hl-img, .care-photo, .ca-img, .strip3 .s, .loc-map{ position:relative; }
.framed .ph, .fd-photo .ph, .funding-photo .ph, .hl-img .ph, .care-photo .ph,
.ca-img .ph, .strip3 .s .ph, .loc-map .ph{ position:absolute; inset:0; }
.ph::before{ content:attr(data-label); position:absolute; left:0; right:0; bottom:0; top:auto;
  height:2.2rem; line-height:2.2rem; padding:0 1rem; margin:0; max-width:100%;
  text-align:center; font-size:.72rem; font-weight:700; letter-spacing:.01em;
  color:var(--primary-ink); background:rgba(255,255,255,.82); backdrop-filter:blur(2px);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; opacity:1; }
.hero .bg .ph::before{ display:none; }

/* C1 - clay trim genuinely behind the photo (opaque photo now occludes top/left) */
.framed-wrap{ position:relative; z-index:0; }
.framed-wrap::before{ inset:auto; top:22px; left:22px; right:-22px; bottom:-22px;
  transform:none; opacity:.6; z-index:0; }
.framed{ z-index:1; background:var(--card); }
.framed-wrap.sm .framed{ background:var(--card); }
@media (max-width:760px){ .framed-wrap::before{ top:12px; left:12px; right:-12px; bottom:-12px; } }

/* C2 - equal-height cards; text length no longer changes box size */
.values-grid, .care-grid, .hl-grid{ align-items:stretch; }
.value, .care-card, .hl{ display:flex; flex-direction:column; height:100%; }
.value{ justify-content:flex-start; }
.value h3 + p{ margin-top:auto; padding-top:.7rem; }
.care-card .care-body, .hl .hl-body{ display:flex; flex-direction:column; flex:1; }
.care-card .care-body p, .hl .hl-body p{ margin-top:.55rem; }

/* C5 - nav link underline slide + consistent focus rings */
/* Direct children only. As a descendant selector this also underlined the links
   inside the "Our Homes" panel, which looked wrong in a dropdown (Jon, 13 Aug 2026). */
.navlinks > a:not(.btn){ position:relative; }
.navlinks > a:not(.btn)::after{ content:""; position:absolute; left:0; right:0; bottom:-5px; height:2px;
  background:var(--cta); border-radius:2px; transform:scaleX(0); transform-origin:left;
  transition:transform .28s var(--ease); }
.navlinks > a:not(.btn):hover::after, .navlinks > a:not(.btn)[aria-current]::after{ transform:scaleX(1); }
.navdrop-m a::after{ display:none; }
a:focus-visible, .btn:focus-visible, button:focus-visible, .home-opt input:focus-visible + label{
  outline:2px solid var(--primary-ink); outline-offset:3px; border-radius:6px; }
.nav:not(.scrolled):not(.solid) .navlinks a:focus-visible,
.nav:not(.scrolled):not(.solid) .nav-tel:focus-visible{ outline-color:#fff; }

/* ============================================================
   ELM ROUND 3 - hero heights (superseded by ROUND 6 below)
   ============================================================ */

/* ============================================================
   ELM ROUND 5 - uniform card photo height (image tops must line up)
   The flex-column cards were sizing the photo to each image's
   natural height; pin the photo to its aspect box and fill it.
   ============================================================ */
.care-card .care-photo, .hl .hl-img{ flex:0 0 auto; }
.care-card .care-photo > img.cover, .hl .hl-img > img.cover{ position:absolute; inset:0; width:100%; height:100%; }

/* ============================================================
   ELM ROUND 6 - the gratwick-standard pass (26 Jul 2026)
   PROMOTE UPSTREAM: every block in here is generic. Copy into
   the Vitality base.css so future clones inherit the fixes.
   ============================================================ */

/* --- 6.1 hero system: gratwick two-height, measured scrim ----
   Home hero taller; every inner page shares one compact hero.
   Phones hold the inner hero to ~58vh so the fold shows content. */
.hero{ min-height:clamp(520px, 80vh, 760px); }
/* R6: support-page heroes brought up close to the home hero's presence */
.hero.compact{ min-height:clamp(520px, 78vh, 730px); }
@media (max-width:640px){
  .hero.compact{ min-height:clamp(460px, 64vh, 580px); }
}

/* Measured scrim. The hero headline sits mid-band where the old
   gradient was weakest (.40), so white sub-copy fell to 2.5:1 on
   the lightest pixels. Deepen the mid stop, add an elliptical
   focus behind the text block, and take a little brightness and
   saturation out of the photograph itself. Target, verified by
   sampling the headline box: lightest pixel luminance <= 0.18,
   which clears 3:1 for the accent and 4.5:1 for white sub-copy. */
.hero .bg > img.cover, .hero .bg > .ph{ filter:saturate(.86) brightness(.80); }
.hero .bg::after{
  background:
    radial-gradient(ellipse 80% 64% at 50% 46%, rgba(16,27,20,.60) 0%, rgba(16,27,20,.34) 55%, transparent 80%),
    var(--scrim);
}

/* Accent over photographs needs real chroma. var(--accent-on-photo) was a pale
   tint that read as washed-out white; this is unmistakably the
   clay accent and still clears 3:1 at hero size. */
.hero h1 .serif{ color:var(--accent-on-photo); }

/* --- 6.2 nav: no overflow anywhere between 700 and 1536 -------
   The old burger breakpoint was 760px, but the full bar stopped
   fitting at about 1130px: the Enquire button ran off-screen and
   body{overflow-x:hidden} swallowed the evidence. Shed the tel
   number first, then switch to the drawer while the bar still
   fits. */
@media (max-width:1240px){
  .navlinks{ gap:1.5rem; }
  .nav .bar{ gap:1rem; }
}
@media (max-width:1160px){
  .nav-tel{ display:none; }
}
@media (max-width:1040px){
  .navlinks{ display:none; }
  .nav-actions .btn{ display:none; }
  .burger{ display:block; }
  .mobile-menu{ display:none; }
  .mobile-menu.open{ display:flex; }
}

/* --- 6.3 anchors must clear the fixed bar -------------------- */
[id]{ scroll-margin-top:156px; }
@media (max-width:1040px){ [id]{ scroll-margin-top:120px; } }

/* --- 6.4 dense rows get quiet separation --------------------
   Four and five column text rows mash together without help:
   hairlines in the gutters, faded at both ends, and headings in
   a fixed two-line box so every paragraph starts level. */
.steps-row > .st, .fsteps > .fstep, .timeline > .tl-item{ position:relative; }
@media (min-width:861px){
  .steps-row{ gap:2.6rem; }
  .steps-row > .st + .st::before,
  .fsteps > .fstep + .fstep::before{
    content:""; position:absolute; left:-1.3rem; top:6%; bottom:6%; width:1px;
    background:linear-gradient(180deg, transparent, var(--rule) 18%, var(--rule) 82%, transparent);
  }
  .steps-row > .st > h3{ min-height:2.6em; display:flex; align-items:flex-end; }
}
@media (max-width:860px){
  .steps-row > .st + .st::before{
    content:""; position:absolute; left:0; right:0; top:-1.1rem; height:1px;
    background:linear-gradient(90deg, transparent, var(--rule) 18%, var(--rule) 82%, transparent);
  }
}

/* --- 6.5 motion: warm, and once ------------------------------
   Elm's .veil element is replaced on this build by the branded
   .loader (see the N-SERIES block at the foot of this file):
   same principle, a CSS animation always clears it, but the mark
   draws itself and it only appears once per browser session. */
/* --- 6.6 inset photo bands read as photographs --------------- */
.strip3 .s{ box-shadow:var(--shadow-sm); }
.strip3 figcaption, .framed-wrap figcaption{
  margin-top:.7rem; font-size:.85rem; color:var(--ink-soft); text-align:left; }

/* --- 6.7 about headings in sentence case ---------------------
   .about-copy h2 was set in uppercase, which suited a short
   address label ("ENYS ROAD, EASTBOURNE") but shouts when the
   heading is a warm sentence. The copy pass made both of these
   headings sentences, so the caps have to go.
   NOT a blanket upstream change: keep the caps option for
   presets whose about heading really is a place label. */
.about-copy h2{ text-transform:none; letter-spacing:-.015em; }

/* ============================================================
   ELM ROUND 7 - Gratwick section components (26 Jul 2026)
   Ported from builds/gratwick-house/site/styles/base.css so the
   two builds share one component set. PROMOTE UPSTREAM.
   ============================================================ */

/* --- 7.1 leaf rule ornament (Gratwick's lotus rule, Elm's mark) --- */
.leaf-rule{ display:flex; align-items:center; justify-content:center; gap:1rem; margin-bottom:1.2rem; }
.leaf-rule .ln{ height:1px; width:clamp(38px,8vw,92px); background:var(--rule); }
.leaf-rule .lf{ width:26px; height:26px; color:var(--accent-line); flex:none; }
.band-deep .leaf-rule .ln{ background:rgba(255,255,255,.25); }
.band-deep .leaf-rule .lf{ color:var(--accent-soft); }

/* --- 7.2 decorative arc behind a centred heading ---------------
   The path is symmetric about x=600 on a 1200 viewBox; measured,
   not eyeballed (a 18px-off apex is the kind of thing Jon feels
   without being able to name it). */
.has-arc{ overflow:hidden; }
.has-arc .arc{ position:absolute; pointer-events:none; color:var(--accent-line); opacity:.18;
  width:min(1100px,120%); left:50%; top:8%; transform:translateX(-50%); z-index:0; }
.has-arc > *{ position:relative; z-index:1; }

/* --- 7.3 line-art icon row ------------------------------------- */
.icon-row{ --ir-gap:clamp(1.8rem,3.4vw,3.2rem);
  margin-top:3.4rem; display:grid; grid-template-columns:repeat(5,1fr); gap:var(--ir-gap); }
.icon-row.four{ grid-template-columns:repeat(4,1fr); }
.icon-row.three{ grid-template-columns:repeat(3,1fr); }
.icon-row .ir{ position:relative; text-align:center; }
.icon-row .ir + .ir::before{ content:""; position:absolute; top:6%; bottom:6%;
  left:calc(var(--ir-gap) / -2); width:1px;
  background:linear-gradient(180deg, transparent 0%, rgba(var(--shadow-rgb),.16) 22%,
    rgba(var(--shadow-rgb),.16) 78%, transparent 100%); }
.icon-row .ir .ico{ width:56px; height:56px; margin:0 auto .95rem; color:var(--primary-ink); }
.icon-row .ir h3{ font-family:var(--body); font-weight:800; font-size:1rem; letter-spacing:.03em;
  min-height:2.2em; }
.icon-row .ir p{ margin-top:.5rem; color:var(--ink-soft); font-size:.96rem; }
@media (max-width:1024px){
  .icon-row, .icon-row.four{ grid-template-columns:repeat(2,1fr); row-gap:2.6rem; }
  .icon-row .ir:nth-child(2n+1)::before{ display:none; }
}
@media (max-width:640px){
  .icon-row, .icon-row.four, .icon-row.three{ grid-template-columns:1fr; row-gap:2.2rem; }
  .icon-row .ir + .ir::before, .icon-row .ir:nth-child(2n+1)::before{ display:block;
    top:calc(var(--ir-gap) / -2 - .35rem); bottom:auto; left:50%; transform:translateX(-50%);
    width:min(220px,52%); height:1px;
    background:linear-gradient(90deg, transparent 0%, rgba(var(--shadow-rgb),.16) 22%,
      rgba(var(--shadow-rgb),.16) 78%, transparent 100%); }
  .icon-row .ir:first-child::before{ display:none; }
}

/* --- 7.4 three doors (call / visit / message) ------------------ */
.doors{ margin-top:2.6rem; display:grid; grid-template-columns:repeat(3,1fr); gap:1.4rem; }
.door{ text-align:center; padding:1.6rem 1rem; }
.door .ico{ width:52px; height:52px; margin:0 auto 1rem; color:var(--accent-soft); }
.door .lab{ display:block; font-size:.78rem; letter-spacing:.18em; text-transform:uppercase; font-weight:800; color:#fff; }
.door .val{ display:inline-flex; align-items:center; gap:.5rem; margin-top:.6rem;
  font-family:var(--display); font-size:1.25rem; color:#fff; }
.door p{ margin-top:.5rem; color:rgba(255,255,255,.76); font-size:.94rem; }
.door a.val:hover{ color:var(--accent-soft); }
@media (max-width:860px){ .doors{ grid-template-columns:1fr; gap:.4rem; } }

/* --- 7.5 note band (a quiet aside inside a copy column) -------- */
.note-band{ border-left:3px solid var(--accent-line); padding:.9rem 0 .9rem 1.3rem; }
.note-band p{ color:var(--ink-soft); }
.note-band b{ color:var(--ink); }

/* --- 7.6 meta line under an accordion body -------------------- */
.acc-meta{ display:block; margin-top:.9rem; font-size:.86rem; font-weight:700;
  letter-spacing:.02em; color:var(--primary-ink); }

/* --- 7.7 areas served chips ----------------------------------- */
.areas{ display:flex; flex-wrap:wrap; gap:.5rem; margin-top:1rem; }
.areas span{ font-size:.9rem; font-weight:600; color:var(--ink-soft);
  border:1px solid var(--rule); border-radius:999px; padding:.35rem .9rem; background:var(--card); }

/* --- 7.8 ask-list (generous checklist, contact page) ----------- */
.asks{ margin-top:2.4rem; display:grid; grid-template-columns:repeat(2,1fr); gap:1.1rem 2.4rem; }
.ask{ display:flex; gap:1rem; align-items:flex-start; padding-bottom:1.1rem; border-bottom:1px solid var(--rule); }
.ask .n{ flex:none; width:30px; height:30px; border-radius:50%; background:var(--band-tint);
  color:var(--primary-ink); display:grid; place-items:center; font-weight:800; font-size:.85rem; }
.ask h3{ font-family:var(--body); font-weight:800; font-size:1rem; }
.ask p{ margin-top:.3rem; color:var(--ink-soft); font-size:.95rem; }
@media (max-width:860px){ .asks{ grid-template-columns:1fr; } }

/* --- 7.9 inset photo band (breaks up a long reading page) ------
   Contained width, rounded, soft shadow, caption underneath.
   Full bleed reads as a section divider; inset reads as a
   photograph, which is what a long text page needs. */
.inset-band{ max-width:980px; margin-inline:auto; }
.inset-band .ph-wrap{ position:relative; border-radius:var(--radius); overflow:hidden;
  box-shadow:var(--shadow); aspect-ratio:16/7; }
.inset-band img{ width:100%; height:100%; object-fit:cover; }
.inset-band figcaption{ margin-top:.85rem; text-align:center; font-size:.9rem; color:var(--ink-soft); }
@media (max-width:640px){ .inset-band .ph-wrap{ aspect-ratio:4/3; } }

/* ============================================================
   N-SERIES - preset 5 (26 Jul 2026)
   New components and preset overrides. Every block is written
   token-only and generic; the ones marked PROMOTE belong in the
   shared library so the next Refresh inherits them.
   ============================================================ */

/* --- N0 buttons: ink on gold ---------------------------------
   This palette's accent is a light aged gold. White on it is
   3.1:1 and fails, so the label is the deep green instead
   (4.57:1) and hover LIGHTENS the fill, which lifts the label
   to 5.9:1 rather than dropping it. design-engine.md allows
   either fill/label direction; measure and pick. PROMOTE the
   pattern, not the values. */
.btn{ color:var(--btn-ink); }
.btn:hover{ color:var(--btn-ink); }
.btn.light{ color:var(--primary-ink); }
.btn.ghost{ color:var(--primary-ink); }
.cta .tel-lg{ color:var(--primary-ink); }
.band-deep .eyebrow{ color:var(--accent-soft); }
.band-accent .eyebrow{ color:var(--gold-ink); }
.care-foot a, .fund-mini .flink, .review .src a, .score .st a,
.qp-card .src a, .care-card .tag{ color:var(--gold-ink); }
.note-band{ border-left:0; padding:0; }

/* --- N3 hero: full bleed, text CENTRED, gold rule ------------
   ROUND 2 (Jon): the left-set hero read as odd; every hero on
   every page is centred. The .left variant is retired sitewide.
   The inner block also carries real bottom padding so the last
   hero line can never touch the section below at any width. */
.hero .inner{ padding-top:7rem; padding-bottom:4.5rem; }
.hero .gold-rule{ display:block; width:64px; height:2px; background:var(--accent-on-photo);
  border-radius:2px; margin:0 auto 1.25rem; }
.hero .hero-tel{ display:block; margin-top:1.5rem; color:rgba(255,255,255,.92);
  font-size:1rem; }
.hero .hero-tel a{ color:#fff; font-weight:800; border-bottom:2px solid var(--accent-on-photo); }

/* --- N4 (retired, ROUND 2) -----------------------------------
   The four-column stat bar read as flat and out of place beside
   the reference builds. Replaced on the home page by an unboxed
   .icon-row of three warm reassurances (the njch principles-row
   move); the facts it stated now live in their best seats only:
   CQC in the CQC section, the room count on the local
   page, 1949 in the history band. */

/* --- N5 D6 cards: photo beside the words ---------------------
   The alternative to an unboxed icon row: each card is a real
   photograph with the writing next to it, which suits a home
   whose photographs are its best asset. PROMOTE as D6
   "photo-side". */
.pcards{ margin-top:2.6rem; display:grid; grid-template-columns:1fr 1fr; gap:1.5rem; }
.pcards.one{ grid-template-columns:1fr; max-width:900px; }
.pcard{ display:grid; grid-template-columns:.82fr 1.18fr; background:var(--card);
  border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow-sm); }
.pcard .pc-photo{ position:relative; min-height:100%; }
.pcard .pc-photo img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.pcard .pc-body{ padding:1.5rem 1.6rem 1.65rem; display:flex; flex-direction:column; }
.pcard h3{ font-size:1.24rem; }
.pcard p{ margin-top:.55rem; color:var(--ink-soft); font-size:1rem; }
.pcard .pc-meta{ margin-top:auto; padding-top:1rem; font-size:.84rem; font-weight:800;
  letter-spacing:.02em; color:var(--gold-ink); }
@media (max-width:1080px){ .pcards{ grid-template-columns:1fr; } }
@media (max-width:560px){
  .pcard{ grid-template-columns:1fr; }
  .pcard .pc-photo{ aspect-ratio:16/9; min-height:0; }
}

/* --- N6 inset framed photographs, captioned (D5) ------------- */
.inset-duo{ margin-top:2.6rem; display:grid; grid-template-columns:1fr 1fr; gap:clamp(1.2rem,2.6vw,2rem); }
.inset-duo figure{ margin:0; }
.inset-duo .if-img{ position:relative; border-radius:var(--radius); overflow:hidden;
  aspect-ratio:4/3; box-shadow:var(--shadow-sm); }
.inset-duo .if-img img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.inset-duo figcaption{ margin-top:.8rem; color:var(--ink-soft); font-size:.9rem; }
@media (max-width:760px){ .inset-duo{ grid-template-columns:1fr; } }

/* --- N7 the year band (history teaser on the deep green) ----- */
.yearband{ display:grid; grid-template-columns:auto 1fr; gap:clamp(1.8rem,4vw,3.6rem);
  align-items:center; }
.yb-year{ font-family:var(--display); font-weight:600; line-height:.9;
  font-size:clamp(3.6rem,8vw,6rem); color:var(--accent-on-photo); }
.yb-copy h2{ color:#fff; }
.yb-copy p{ margin-top:1rem; color:rgba(255,255,255,.84); font-size:1.06rem; max-width:56ch; }
.yb-copy .flink{ display:inline-block; margin-top:1.3rem; font-weight:800;
  color:var(--accent-soft); text-decoration:underline; }
@media (max-width:700px){ .yearband{ grid-template-columns:1fr; gap:1rem; } }

/* --- N8 verbatim reviews + score (ported from Gratwick) ------ */
.score{ display:flex; align-items:center; gap:clamp(1.3rem,3vw,2.4rem); flex-wrap:wrap;
  background:var(--card); border-radius:var(--radius); box-shadow:var(--shadow-sm);
  padding:clamp(1.5rem,3vw,2.3rem) clamp(1.5rem,3.4vw,2.8rem); }
.score .num{ flex:none; width:108px; height:108px; border-radius:50%; background:var(--band-tint);
  display:grid; place-items:center; font-family:var(--display); font-weight:600;
  font-size:2.2rem; color:var(--primary-ink); line-height:1; }
.score .st{ flex:1; min-width:270px; }
.score .st b{ font-family:var(--body); font-weight:800; font-size:1.1rem; display:block; }
.score .st p{ color:var(--ink-soft); margin-top:.45rem; font-size:.97rem; max-width:74ch; }
.reviews{ margin-top:2.4rem; display:grid; grid-template-columns:1fr 1fr; gap:1.5rem; align-items:stretch; }
.reviews.single{ grid-template-columns:1fr; max-width:820px; margin-inline:auto; }
.review{ background:var(--card); border-radius:var(--radius); box-shadow:var(--shadow-sm);
  padding:clamp(1.5rem,2.4vw,2.1rem); display:flex; flex-direction:column; height:100%; }
.review .marks{ font-family:var(--display); font-weight:600; font-size:2.6rem; line-height:.5;
  color:var(--accent-line); display:block; height:1.1rem; }
.review blockquote{ margin-top:1rem; color:var(--ink); font-size:1.03rem; line-height:1.72; }
.review .attr{ margin-top:auto; padding-top:1.3rem; }
.review .attr b{ font-family:var(--body); font-weight:800; color:var(--ink); }
.review .attr span{ display:block; color:var(--ink-soft); font-size:.9rem; margin-top:.15rem; }
.review .src{ margin-top:.85rem; font-size:.82rem; color:var(--ink-soft); }
@media (max-width:860px){ .reviews{ grid-template-columns:1fr; } }

/* --- N9 photo band, inset not full bleed (from Gratwick) ----- */
.photoband{ padding-block:clamp(1rem,2.4vw,2rem); }
.photoband .pb-hold{ max-width:var(--hold); margin-inline:auto; padding-inline:var(--w1); }
.photoband figure{ margin:0; }
.photoband .pb-img{ position:relative; overflow:hidden; border-radius:var(--radius);
  aspect-ratio:16/7; box-shadow:var(--shadow-sm); }
.photoband .pb-img img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.photoband figcaption{ margin-top:.85rem; color:var(--ink-soft); font-size:.92rem; text-align:center; }
@media (max-width:700px){ .photoband .pb-img{ aspect-ratio:4/3; } }

/* --- N10 the day list (a day here, without a numbered rota) --
   The numbered timeline says "step 1 of 5", which is wrong for a
   day. Time-of-day labels on a hairline rail say "this is roughly
   how a day goes". PROMOTE. */
.daylist{ margin-top:2.6rem; max-width:760px; margin-inline:auto; }
.dl{ display:grid; grid-template-columns:9.5rem 1fr; gap:1.6rem; padding:1.5rem 0;
  border-top:1px solid var(--rule); position:relative; }
.dl:last-child{ border-bottom:1px solid var(--rule); }
.dl .when{ font-family:var(--display); font-weight:600; font-size:1.12rem; color:var(--primary-ink);
  padding-left:1.15rem; position:relative; }
.dl .when::before{ content:""; position:absolute; left:0; top:.55em; width:7px; height:7px;
  border-radius:50%; background:var(--accent-line); }
.dl p{ color:var(--ink-soft); }
@media (max-width:620px){
  .dl{ grid-template-columns:1fr; gap:.5rem; }
}

/* --- N13 quiet aside inside a copy column (card, not a stripe) */
.qnote{ background:var(--band-tint); border-radius:var(--radius-sm); padding:1.2rem 1.4rem;
  margin-top:1.7rem; max-width:56ch; }
.qnote blockquote{ font-family:var(--display); font-weight:600; font-style:italic;
  font-size:1.16rem; line-height:1.5; color:var(--ink); }
.qnote figcaption{ margin-top:.7rem; font-size:.86rem; color:var(--ink-soft); }
.qnote figcaption b{ font-family:var(--body); font-weight:800; color:var(--ink); }
.qnote a{ color:var(--primary-ink); font-weight:700; text-decoration:underline; }

/* --- N14 the quiet local line (links the local landing page) - */
.localline{ margin-top:1.8rem; font-size:.98rem; color:var(--ink-soft); }
.localline a{ color:var(--primary-ink); font-weight:800; text-decoration:underline; }

/* --- N15 fees note ------------------------------------------- */
.feesrow{ display:grid; grid-template-columns:.94fr 1.06fr; gap:clamp(2rem,4vw,3.4rem); align-items:center; }
.feesrow .fr-copy .lede{ margin-top:1rem; color:var(--ink-soft); font-size:1.08rem; max-width:48ch; }
.feesrow .fr-list{ margin-top:1.4rem; display:flex; flex-direction:column; gap:.8rem; }
.feesrow .fr-list div{ display:flex; gap:.75rem; align-items:flex-start; color:var(--ink-soft); font-size:1rem; }
.feesrow .fr-list svg{ flex:none; color:var(--primary); margin-top:.28rem; }
.feesrow .fr-list b{ color:var(--ink); font-family:var(--body); font-weight:800; }
.feesrow .fr-photo{ border-radius:var(--radius); overflow:hidden; aspect-ratio:auto;
  align-self:stretch; min-height:clamp(400px,36vw,540px);
  box-shadow:var(--shadow); position:relative; }
.feesrow .fr-photo img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
@media (max-width:1000px){ .feesrow{ grid-template-columns:1fr; }
  .feesrow .fr-photo{ order:-1; aspect-ratio:4/3; align-self:auto; min-height:0; } }

/* --- N16 hero refinements for this palette -------------------
   The library's inner-page hero filter and radial focus, tuned so
   the measured lightest pixel behind the headline stays dark
   enough for the gold italic word (needs 3:1) and white body
   copy (needs 4.5:1). Measured in QA, see BUILD_NOTES. */
/* R1.6 The .66 brightness was tuned against a flat brand field. Over the real
   photographs it made both houses read as a dark, dramatic backdrop, which is
   the opposite of what this site is for (Jon, round 1). Photographs are lifted
   to .90; the brand field, which has no detail to lose, stays dark. Worst-case
   pixel behind every hero text box re-measured at 390 and 1920 afterwards. */
.hero .bg > .ph{ filter:saturate(.90) brightness(.66); }
.hero .bg > img.cover{ filter:saturate(.94) brightness(.86); }
.hero h1 .serif{ color:var(--accent-on-photo); }
.hero .eyebrow{ color:rgba(255,255,255,.93); }  /* measured: gold at eyebrow size fell to 3.9:1 on the
                                              lightest hero pixels and small text needs 4.5:1 */

/* --- N17 small odds and ends --------------------------------- */
.sub-tight{ max-width:52ch; }
.section-head .say a{ color:var(--primary-ink); font-weight:700; text-decoration:underline; }
.prose h2{ font-family:var(--display); }
.foot .fbird{ width:30px; height:23px; color:var(--accent-soft); margin-bottom:.7rem; display:block; }
.foot .est{ display:block; margin-top:.9rem; font-size:.82rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--accent-soft); font-weight:800; }
.hold.narrow{ max-width:1020px; }
.acc-body-inner p + p{ margin-top:.8rem; }
.cqc-chip .ct p a{ color:var(--primary-ink); font-weight:700; text-decoration:underline; }
.band-deep .cqc-chip .ct p a{ color:var(--accent-soft); }
.map-note{ margin-top:1rem; color:var(--ink-soft); font-size:.92rem; }

/* --- N18 skip link + focus rings (ported from Gratwick; the Elm copy of the
   library never had a .skip rule, so its skip link rendered as visible text
   at the top of every page. PROMOTE UPSTREAM. ) --- */
.skip{ position:absolute; left:-9999px; top:0; z-index:300; background:var(--card);
  color:var(--primary-ink); font-weight:800; padding:.85rem 1.3rem; border-radius:0 0 12px 0; }
.skip:focus{ left:0; }
a:focus-visible, .btn:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible{
  outline:2px solid var(--primary-ink); outline-offset:3px; border-radius:6px; }
.nav:not(.scrolled) .navlinks a:focus-visible,
.nav:not(.scrolled) .nav-tel:focus-visible,
.band-deep a:focus-visible, .band-deep button:focus-visible,
.hero a:focus-visible{ outline-color:#fff; }

/* --- N19 accordions must survive a failed script ------------
   LIBRARY BUG, found here: .acc-body was collapsed by CSS
   (max-height:0) and only ever opened by script.js, so with
   JavaScript off, or with script.js blocked, every accordion
   panel on Gratwick and Elm is invisible. Gate the collapse on
   the same boot flag the reveals use, so no JavaScript means all
   panels are simply open. PROMOTE UPSTREAM. */
.acc-body{ max-height:none; }
html.reveal-ready .acc-body{ max-height:0; }
.no-js .acc-body{ max-height:none; }

/* --- N20 fees table (plain, readable, no zebra stripes) ------ */
.feetable{ width:100%; border-collapse:collapse; margin-top:1.8rem; background:var(--card);
  border-radius:var(--radius-sm); overflow:hidden; box-shadow:var(--shadow-sm); }
.feetable caption{ text-align:left; color:var(--ink-soft); font-size:.92rem; margin-bottom:.8rem; }
.feetable th, .feetable td{ text-align:left; padding:.95rem 1.2rem; border-bottom:1px solid var(--rule); }
.feetable thead th{ font-family:var(--body); font-weight:800; font-size:.78rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--gold-ink); background:var(--surface); }
.feetable tbody th{ font-family:var(--body); font-weight:700; color:var(--ink); font-size:1rem; }
.feetable td{ color:var(--ink-soft); font-weight:700; white-space:nowrap; }
.feetable tr:last-child th, .feetable tr:last-child td{ border-bottom:0; }
@media (max-width:560px){
  .feetable th, .feetable td{ padding:.8rem .9rem; font-size:.94rem; }
  .feetable thead th{ font-size:.68rem; letter-spacing:.1em; }
}

/* --- N21 form states the Elm copy of the library was missing --
   Ported from Gratwick: error text, invalid field borders, the
   send-failure box, a bigger tap target on inputs, and the mobile
   drawer's phone number. The Elm base.css had the form markup
   classes but none of these, so an invalid field showed nothing.
   PROMOTE UPSTREAM. */
.field input, .field select, .field textarea{ min-height:48px; padding:.85rem .9rem; }
.field input::placeholder, .field textarea::placeholder{ color:var(--ink-soft); opacity:1; }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"]{ border-color:var(--cta); }
.field .err{ display:none; margin-top:.35rem; font-size:.86rem; font-weight:700; color:var(--gold-ink); }
.field.bad .err{ display:block; }
.consent input{ width:20px; height:20px; margin-top:.1rem; flex:none; min-height:0;
  accent-color:var(--primary); cursor:pointer; }
.form-error{ display:none; margin-top:1rem; background:var(--accent-tint); border-radius:12px;
  padding:1rem 1.2rem; color:var(--ink); font-size:.95rem; }
.form-error.show{ display:block; }
.form-error a{ color:var(--gold-ink); font-weight:800; }
.enq-success p a{ color:var(--gold-ink); font-weight:800; }
@media (max-width:1040px){
  .mobile-menu a.mm-tel{ color:var(--primary-ink); font-family:var(--display); font-size:1.2rem; }
}

/* --- N22 mobile drawer must be styled at the SAME width the
   burger appears. ROUND 6.2 moved the burger to 1040px but left
   the drawer's own styling (absolute position, background, stacked
   links) in the old 760px block, so between 761 and 1040 the menu
   opened as an unstyled row over the hero. LIBRARY BUG.
   PROMOTE UPSTREAM. */
@media (max-width:1040px){
  .mobile-menu{ position:absolute; left:0; right:0; top:100%; background:var(--surface);
    border-bottom:1px solid var(--rule); box-shadow:var(--shadow-sm); padding:.6rem var(--w1) 1.4rem; }
  .mobile-menu.open{ display:flex; flex-direction:column; }
  .mobile-menu a{ padding:.95rem .2rem; font-weight:700; border-bottom:1px solid var(--rule); color:var(--ink); }
  .mobile-menu a.btn{ margin-top:1rem; border-bottom:none; color:var(--btn-ink); justify-content:center; }
}

/* --- N23 reduced motion has to beat the reveal gate -----------
   LIBRARY BUG: the reduced-motion rule was written as `.reveal`
   (specificity 0,1,0) while the gate is `html.reveal-ready
   .reveal` (0,2,1), so on a machine that asks for reduced motion
   every off-screen section still started at opacity 0 and only
   appeared when the observer fired. Same selector weight fixes
   it, no !important needed. PROMOTE UPSTREAM. */
@media (prefers-reduced-motion: reduce){
  html.reveal-ready .reveal{ opacity:1; transform:none; transition:none; }
  html.reveal-ready .reveal.scale{ transform:none; }
}
/* with no JavaScript every panel is open, so the toggle should read as a minus */
.no-js .acc-head .pm::after{ transform:translateX(-50%) scaleY(0); }
/* an embedded map that has not loaded yet should read as a quiet panel, not a
   white hole in the page */
.loc-map{ background:var(--band-tint); }

/* ============================================================
   N-SERIES ROUND 2 (Jon's review, 3 Aug 2026)
   ============================================================ */

/* --- R2.1 quieter section spacing for interstitial rows ------ */
.section.snug{ padding-block:calc(var(--sp) * .68); }

/* --- R2.2 photo-side care cards: even crops ------------------
   The photo strip was collapsing to a sliver wherever a card's
   text ran long. Give the photo column real width and a floor,
   so all four cards read as photographs, not slivers. Scoped
   above 560px so the phone stack (1 column, 16/9 photo) from the
   base rules still wins on small screens. */
@media (min-width:561px){
  .pcard{ grid-template-columns:.95fr 1.05fr; }
  .pcard .pc-photo{ min-height:230px; }
}

/* --- R2.3 the day, as a line -------------------------------
   Replaces the bullet-and-rule .daylist: a single gold spine,
   line-art time-of-day medallions, display-face moments. Keeps
   every fact, loses the enormous flat list. */
.dayline{ margin:2.8rem auto 0; max-width:820px; position:relative; }
/* R3.3: the spine is now drawn per item, from each medallion's centre to the
   next one's, so it starts at the first icon and stops dead at the last
   instead of overshooting the content at both ends. */
.dayline .dli::after{ content:""; position:absolute; left:31px;
  top:calc(1.35rem + 32px); bottom:calc(-1.35rem - 32px); width:1.5px;
  background:var(--accent-line); opacity:.65; }
.dayline .dli:last-child::after{ display:none; }
.dayline .dli{ position:relative; display:grid; grid-template-columns:64px 1fr;
  gap:clamp(1.2rem,3vw,2rem); padding-block:1.35rem; align-items:start; }
.dayline .dli .dico{ position:relative; z-index:1; width:64px; height:64px; border-radius:50%;
  background:var(--card); border:1px solid var(--rule); display:grid; place-items:center;
  color:var(--primary-ink); box-shadow:0 10px 24px -18px rgba(24,47,39,.5); }
.dayline .dli .dico svg{ width:30px; height:30px; }
.dayline .dli .dbody .when{ font-family:var(--display); font-weight:600; font-size:1.22rem;
  color:var(--ink); }
.dayline .dli .dbody p{ margin-top:.4rem; color:var(--ink-soft); max-width:56ch; }
@media (max-width:560px){
  .dayline .dli::after{ left:23px; top:calc(1.35rem + 24px); bottom:calc(-1.35rem - 24px); }
  .dayline .dli{ grid-template-columns:48px 1fr; gap:1rem; }
  .dayline .dli .dico{ width:48px; height:48px; }
  .dayline .dli .dico svg{ width:24px; height:24px; }
}
.dayfoot{ margin:3.2rem auto 0; max-width:62ch; text-align:center; }
.dayfoot h3{ font-family:var(--body); font-weight:800; font-size:1.06rem; }
.dayfoot p{ margin-top:.7rem; color:var(--ink-soft); font-size:1rem; }

/* --- R2.4 icon-row placement helpers -------------------------
   .below: the feature row under the nursing intro on Our Care.
   .solo: a row standing alone in its own section (home page
   reassurance row), so it carries no stray top margin. */
.icon-row.below{ margin-top:clamp(3.6rem,6.5vw,5.4rem); }
.icon-row.solo{ margin-top:0; }
.inset-duo.solo{ margin-top:0; }

/* --- R3.1 the CQC "Good", highlighted in green ---------------
   One word, one colour, nothing shouting: the italic display
   word picks up a CQC-family green. 4.8:1 on the cream, well
   clear of the 3:1 large-text floor. */
.section-head .good{ color:var(--cqc-good); }

/* --- R3.2 the callers row (replaces the plain-text dayfoot) --
   Who comes to the house, as quiet white chips with line-art
   marks, sitting on the gold band. */
.callers{ margin:3.4rem auto 0; max-width:820px; text-align:center; }
.callers h3{ font-family:var(--display); font-weight:600; font-size:clamp(1.4rem,2.6vw,1.8rem); color:var(--ink); }
.callers h3 .serif{ font-style:italic; color:var(--gold-ink); }
.callers > p{ margin:.8rem auto 0; color:var(--ink-soft); font-size:1rem; max-width:56ch; }
.caller-row{ margin-top:1.7rem; display:flex; flex-wrap:wrap; justify-content:center; gap:.8rem; }
.caller{ display:inline-flex; align-items:center; gap:.6rem; background:var(--card);
  border:1px solid var(--rule); border-radius:999px; padding:.68rem 1.25rem;
  font-family:var(--body); font-weight:700; font-size:.95rem; color:var(--ink);
  box-shadow:0 10px 22px -18px rgba(var(--shadow-rgb),.55); }
.caller svg{ width:21px; height:21px; flex:none; color:var(--primary-ink); }
.callers .caller-note{ margin:1.5rem auto 0; color:var(--ink-soft); font-size:.92rem; max-width:52ch; }

/* --- R6.1 the reviews page, Gratwick treatment (Jon's call after
   seeing both): score row, featured quote on a photograph, then
   recent and earlier review cards. .score and .reviews already
   live in this stylesheet; only the quote-photo needed porting. */
.quote-photo{ position:relative; min-height:clamp(460px,58vw,620px); display:grid; align-items:center; }
.quote-photo .qp-bg{ position:absolute; inset:0; overflow:hidden; }
.quote-photo .qp-bg img.cover{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.quote-photo .qp-bg::after{ content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, rgba(var(--shadow-rgb),.72) 0%, rgba(var(--shadow-rgb),.34) 62%, rgba(var(--shadow-rgb),.5) 100%); }
.qp-hold{ position:relative; z-index:2; max-width:var(--hold); margin-inline:auto;
  padding-inline:var(--w1); padding-block:clamp(1.6rem,4.5vw,2.6rem); width:100%; }
.qp-card{ background:var(--card); border-radius:var(--radius); box-shadow:var(--shadow);
  padding:clamp(1.8rem,3.4vw,3rem); max-width:38rem; }
.qp-card .marks{ font-family:var(--display); font-weight:600; font-size:3.4rem; line-height:.6;
  color:var(--accent-line); display:block; height:1.6rem; }
.qp-card blockquote{ font-family:var(--display); font-weight:500;
  font-size:clamp(1.18rem,1.72vw,1.42rem); line-height:1.62; color:var(--ink); margin-top:1.1rem; }
.qp-card .attr{ margin-top:1.5rem; font-weight:800; color:var(--ink); }
.qp-card .attr span{ display:block; font-weight:600; color:var(--ink-soft); font-size:.92rem; margin-top:.2rem; }
.qp-card .src{ margin-top:1.2rem; padding-top:1.1rem; border-top:1px solid var(--rule);
  font-size:.88rem; color:var(--ink-soft); }
@media (prefers-reduced-motion:reduce){ .fl-tilt svg{ animation:none; } }
.rowband{ background:var(--card); border-top:1px solid var(--rule); border-bottom:1px solid var(--rule); }

/* ============================================================
   S BLOCK: THE DUAL-HOME ENGINE (build 7, 12 Aug 2026)
   Everything above this line is shared library code inherited
   from the N-series build copy of base.css (which carries Vitality
   v0.4 + Elm rounds 6-7 + the Gratwick component port + the
   the N-series build rounds). The N-series build's own mark, veil, story rail,
   flight and album components were stripped on clone because
   nothing here uses them.
   Everything below is either a NEW component this build earned
   (marked PROMOTE) or a preset override from that build.
   ============================================================ */

/* --- S0 palette housekeeping -------------------------------
   The inherited hero scrim hard-codes a green rgba() from the
   the N-series build. Re-point it at the shadow token so the
   whole page really does come out of tokens.css. PROMOTE. */
.hero .bg::after{
  background:
    radial-gradient(ellipse 80% 64% at 50% 46%, rgba(var(--shadow-rgb),.58) 0%, rgba(var(--shadow-rgb),.32) 55%, transparent 80%),
    var(--scrim);
}
.nav.scrolled{ background:rgba(250,247,241,.95); box-shadow:0 10px 30px -24px rgba(var(--shadow-rgb),.45); }

/* --- S1 brand mark: the SH monogram + wordmark --------------
   Redrawn from the client's own logo files rather than from
   memory: a solid disc with reversed-out "SH", then the name in
   two lines of serif caps. The real vector has not been supplied
   (GAPS 2), so this is a faithful stand-in, flagged in
   BUILD_NOTES for replacement. */
.brand{ gap:.7rem; }
.brand .disc{ width:38px; height:38px; flex:none; border-radius:50%; background:currentColor;
  display:grid; place-items:center; transition:background .3s; }
.brand .disc span{ font-family:var(--display); font-weight:600; font-size:.92rem; letter-spacing:.02em;
  color:var(--primary-deep); transition:color .3s; }
.nav.scrolled .brand .disc span{ color:#fff; }
.brand .wm{ display:flex; flex-direction:column; line-height:1.02; }
.brand .wm b{ font-family:var(--display); font-weight:600; font-size:1.26rem; letter-spacing:.005em; }
.brand .wm i{ font-style:normal; font-family:var(--body); font-weight:700; font-size:.6rem;
  letter-spacing:.24em; text-transform:uppercase; opacity:.78; margin-top:.16rem; }
@media (min-width:1041px) and (max-width:1200px){ .brand .wm b{ font-size:1.06rem; } .brand .disc{ width:32px; height:32px; } }
@media (max-width:430px){ .brand .wm b{ font-size:1.06rem; } .brand .disc{ width:32px; height:32px; } }

/* --- S2 first-load veil: the disc draws itself --------------
   Once per browser session (sessionStorage), and a CSS animation
   always clears it, so a failed script never leaves it up. */
/* Timing: the disc finishes drawing at 1.25s and the wordmark finishes fading in
   at 1.6s, but the veil used to start leaving at 1.5s, so the finished mark was
   never actually seen. It now HOLDS for about half a second once complete before
   fading (Jon, 13 Aug 2026: "let the loader sit a smidge once fully loaded").
   script.js uses the same 1.95s figure so the two never disagree. */
.loader{ position:fixed; inset:0; z-index:900; background:var(--primary-deep); display:grid; place-items:center;
  /* TWO exit paths, and they must not race. script.js lifts the veil at 1.95s using
     the transition below, which is the fade people actually see. The keyframe is only
     a safety net for a session where script.js never boots, so it starts LATER (3.2s)
     than the JS lift. When both were set to the same figure the animation won, overrode the
     inline opacity, and the veil cut rather than faded (Jon: "snaps too aggressively"). */
  animation:veilout 1.05s cubic-bezier(.33,0,.2,1) 3.2s forwards;
  transition:opacity 1.05s cubic-bezier(.33,0,.2,1); }
/* the mark leaves BEFORE the ground does, and drifts up as it goes, so the veil
   reads as a curtain lifting rather than the whole thing switching off at once.
   Softened 6 Sep 2026 at Jon's request: longer, and eased out rather than in. */
.loader .lmark{ transition:opacity .58s ease, transform 1.05s cubic-bezier(.33,0,.2,1); }
.loader.going .lmark{ opacity:0; transform:translateY(-14px); }
.loader .lmark{ display:grid; place-items:center; gap:.9rem; color:var(--primary); }
.loader .ldisc{ width:74px; height:74px; }
.loader .ldisc circle{ fill:none; stroke:currentColor; stroke-width:3; stroke-dasharray:220; stroke-dashoffset:220;
  animation:draw 1.15s var(--ease) .1s forwards; }
.loader .ldisc text{ fill:currentColor; opacity:0; animation:fadein .5s ease .85s forwards; }
.loader .lwm{ font-family:var(--display); font-weight:600; font-size:1.06rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--accent-soft); opacity:0; animation:fadein .6s ease 1s forwards; }
@keyframes draw{ to{ stroke-dashoffset:0; } }
@keyframes fadein{ to{ opacity:1; } }
@keyframes veilout{ to{ opacity:0; visibility:hidden; } }
.no-js .loader, html.veilseen .loader{ display:none; }
@media (prefers-reduced-motion:reduce){
  .loader{ animation:veilout .2s linear forwards; }
  .loader .ldisc circle{ animation:none; stroke-dashoffset:0; }
  .loader .ldisc text,.loader .lwm{ animation:none; opacity:1; }
}

/* --- S3 the brand field (D1 hero background, no photograph) --
   No client photography exists yet (GAPS 2). Rather than ship a
   grey box behind the biggest headline on the site, the hero
   sits on a designed brand surface: espresso base, one soft gold
   bloom, one large thin arc. It is deliberate on its own terms
   and it swaps for a photograph by replacing the div with the
   usual <img class="cover">, nothing else. PROMOTE. */
.brandfield{ position:absolute; inset:0; background:var(--primary-deep); overflow:hidden; }
.brandfield::before{ content:""; position:absolute; inset:-20%;
  background:
    radial-gradient(ellipse 52% 58% at 74% 22%, var(--field-bloom-a) 0%, var(--field-bloom-a0) 68%),
    radial-gradient(ellipse 66% 70% at 12% 88%, var(--field-bloom-b) 0%, var(--field-bloom-b0) 70%); }
.brandfield .arc{ position:absolute; right:-14%; bottom:-42%; width:min(96vw,1180px); height:auto;
  color:var(--accent-line); opacity:.24; }
.brandfield .arc2{ position:absolute; left:-26%; top:-38%; width:min(72vw,860px); height:auto;
  color:var(--accent-line); opacity:.14; }
/* The field is already dark, so it does not want the photo scrim's
   brightness knock-down, only the readability wash. */
.hero .bg > .brandfield{ filter:none; }
/* ...and it does not want the photo VIGNETTE either. The .bg::after wash exists to
   hold text over a bright photograph; over a designed dark field it only muddies
   the brand colour, which is why the gold bloom measured invisible on the first
   render. White on the field is 14.08:1 with no wash at all. PROMOTE UPSTREAM:
   every photoless build in the library inherits this fault. */
.hero .bg:has(> .brandfield)::after{ display:none; }

/* --- S4 hero, text LEFT (D1) --------------------------------
   Vitality centres its hero, the N-series build left-aligns a plain one.
   The dual-home engine's hero is left-aligned. */
.hero.left .inner{ text-align:left; margin-inline:0; max-width:min(58rem,100%);
  padding-inline:var(--w1); }
.hero.left .hold-in{ max-width:var(--hold); margin-inline:auto; width:100%; position:relative; z-index:2; }
.hero.left .sub{ margin-inline:0; max-width:46ch; }
.hero.left .cta-row{ justify-content:flex-start; }
.gold-rule{ display:block; width:74px; height:3px; border-radius:2px; background:var(--primary); margin-bottom:1.4rem; }
.hero .hero-tel{ display:block; margin-top:1.5rem; color:rgba(255,255,255,.86); font-size:.98rem; }
/* One underline, not two. The base hero rule underlines these links with a gold
   2px border-bottom; this block later added a text-decoration underline as well,
   so every hero phone number rendered with a white underline AND a gold bar
   below it (Jon, 13 Aug 2026: "remove the second yellow underline"). The
   text-decoration is the one that reads as the link, so the border is unset.
   PROMOTE UPSTREAM: same collision exists anywhere both mechanisms are used. */
.hero .hero-tel a{ color:#fff; font-weight:700; text-decoration:underline; text-underline-offset:3px; border-bottom:0; }


/* --- S5 key-info strip (D2, second half) --------------------
   The slim factual strip under the editorial welcome. Every fact
   on it is spent here and nowhere else (thin-facts rule). PROMOTE. */
.keystrip{ display:grid; grid-template-columns:repeat(4,1fr); gap:0; background:var(--card);
  border:1px solid var(--rule); border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow-sm); }
.keystrip .k{ padding:1.5rem 1.5rem 1.6rem; position:relative; }
.keystrip .k + .k::before{ content:""; position:absolute; left:0; top:18%; bottom:18%; width:1px;
  background:linear-gradient(180deg,transparent,var(--rule) 22%,var(--rule) 78%,transparent); }
.keystrip .k b{ display:block; font-family:var(--display); font-weight:600; font-size:1.32rem; color:var(--ink); line-height:1.15; }
.keystrip .k span{ display:block; margin-top:.4rem; font-size:.9rem; color:var(--ink-soft); }
.keystrip .k svg{ width:24px; height:24px; color:var(--primary-ink); margin-bottom:.7rem; }
@media (max-width:900px){ .keystrip{ grid-template-columns:repeat(2,1fr); }
  .keystrip .k:nth-child(3)::before,.keystrip .k:nth-child(2)::before{ }
  .keystrip .k:nth-child(odd)::before{ display:none; }
  .keystrip .k:nth-child(n+3){ border-top:1px solid var(--rule); } }
@media (max-width:520px){ .keystrip{ grid-template-columns:1fr; }
  .keystrip .k::before{ display:none; }
  .keystrip .k + .k{ border-top:1px solid var(--rule); } }

/* --- S6 homes, 2-up (D4) ------------------------------------
   Vitality's hover-reveal card grid, taken to two columns and
   given a real anchor per card instead of an onclick handler, so
   it is keyboard reachable. Badge overlay from njch. PROMOTE the
   anchor fix upstream: the 3-up version has the same fault. */
.homes-grid.two{ grid-template-columns:repeat(2,1fr); gap:1.8rem; }
.homes-grid.two .home-card{ aspect-ratio:4/3.1; }
.home-card .cardlink{ position:absolute; inset:0; z-index:4; }
.home-card .cardlink span{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
.home-card:focus-within .scrim{ background:linear-gradient(180deg, rgba(var(--shadow-rgb),.15) 0%, rgba(var(--shadow-rgb),.9) 100%); }
.home-card:focus-within .label .more{ max-height:260px; opacity:1; margin-top:.9rem; }
.home-card .scrim{ background:linear-gradient(180deg, rgba(var(--shadow-rgb),0) 34%, rgba(var(--shadow-rgb),.82) 100%); }
.home-card:hover .scrim{ background:linear-gradient(180deg, rgba(var(--shadow-rgb),.15) 0%, rgba(var(--shadow-rgb),.9) 100%); }
.home-card .badge{ position:absolute; top:1.1rem; left:1.1rem; z-index:3; background:rgba(250,247,241,.95);
  color:var(--ink); border-radius:999px; padding:.45rem 1rem; font-size:.8rem; font-weight:700;
  box-shadow:var(--shadow-sm); }
.home-card .label h3{ font-size:clamp(1.5rem,2.4vw,2rem); }
.home-card .label .place{ color:var(--accent-soft); }
/* RAISED from 820 to 1000 on 6 Sep 2026, and the reason is measured. Between
   821 and 1000 the two cards are only about 340px wide and 265px tall, and the
   revealed description needs roughly 340px of height, so it grew past the top of
   a card that clips its overflow and the first two lines were simply cut off.
   A card that narrow has no business carrying a hover reveal at all, so the
   grid now goes to one column, and Y9 below turns it into a picture with its
   caption underneath. PROMOTE UPSTREAM. */
@media (max-width:1000px){ .homes-grid.two{ grid-template-columns:1fr; }
  .homes-grid.two .home-card{ aspect-ratio:4/3; }
  .home-card .label .more{ max-height:340px; opacity:1; margin-top:.9rem; } }

/* --- S8 regulation blocks ----------------------------------
   One isolated block per home. The two regulators never share a
   treatment beyond the shared chip shell, and neither block ever
   borrows a regulator's logo or colours. */
.cqc-chip{ align-items:flex-start; }
.cqc-chip .ct b{ font-family:var(--body); font-weight:800; font-size:.82rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-soft); display:block; }
.cqc-chip .ct .rate{ display:flex; flex-wrap:wrap; gap:.5rem; margin-top:1rem; }
.cqc-chip .ct .rate i{ font-style:normal; background:var(--band-tint); border-radius:999px;
  padding:.4rem .95rem; font-size:.88rem; font-weight:700; color:var(--ink); }
.cqc-chip .ct .rate i b{ display:inline; font-family:var(--body); font-size:.88rem; letter-spacing:0;
  text-transform:none; color:var(--good); font-weight:800; }
.cqc-chip .checked{ display:block; margin-top:1rem; font-size:.86rem; color:var(--ink-soft); }
.good{ color:var(--good); }

/* --- S10 team cards ----------------------------------------- */
.teamlead{ display:grid; grid-template-columns:.85fr 1.15fr; gap:clamp(2rem,4vw,3.6rem); align-items:center; }
.teamlead .tl-photo{ border-radius:var(--radius); overflow:hidden; aspect-ratio:4/5; position:relative;
  box-shadow:var(--shadow); }
.teamlead .tl-photo .ph{ position:absolute; inset:0; }
.teamlead blockquote{ font-family:var(--display); font-weight:500; font-style:italic;
  font-size:clamp(1.16rem,1.9vw,1.44rem); line-height:1.55; color:var(--ink); margin-top:1.3rem;
  padding-left:1.3rem; border-left:2px solid var(--primary); }
.people{ margin-top:2.6rem; display:grid; grid-template-columns:repeat(2,1fr); gap:1.6rem; }
.person{ background:var(--card); border:1px solid var(--rule); border-radius:var(--radius); overflow:hidden;
  display:grid; grid-template-columns:11.5rem 1fr; }
.person .p-photo{ position:relative; min-height:100%; }
.person .p-photo .ph{ position:absolute; inset:0; }
.person .p-body{ padding:1.5rem 1.6rem 1.7rem; }
.person .p-role{ font-size:.76rem; letter-spacing:.16em; text-transform:uppercase; font-weight:800; color:var(--primary-ink); }
.person h3{ margin-top:.35rem; font-size:1.3rem; }
.person p{ margin-top:.6rem; color:var(--ink-soft); font-size:.98rem; }
@media (max-width:1000px){ .teamlead{ grid-template-columns:1fr; } .teamlead .tl-photo{ aspect-ratio:4/3; }
  .people{ grid-template-columns:1fr; } }
@media (max-width:520px){ .person{ grid-template-columns:1fr; } .person .p-photo{ aspect-ratio:4/3; } }

/* --- S11 fees tables ---------------------------------------- */
.feeblock + .feeblock{ margin-top:2.8rem; }
.feeblock h3{ font-size:1.5rem; }
.feetable{ width:100%; border-collapse:collapse; margin-top:1.1rem; background:var(--card);
  border:1px solid var(--rule); border-radius:var(--radius); overflow:hidden; }
.feetable caption{ text-align:left; font-size:.9rem; color:var(--ink-soft); padding-bottom:.7rem; }
.feetable th,.feetable td{ text-align:left; padding:.9rem 1.15rem; border-bottom:1px solid var(--rule); font-size:1rem; }
.feetable th{ font-family:var(--body); font-weight:800; color:var(--ink); font-size:.88rem;
  letter-spacing:.06em; text-transform:uppercase; }
.feetable tr:last-child td{ border-bottom:0; }
.feetable td b{ font-family:var(--body); font-weight:800; }
.todo{ background:var(--band-tint); border-radius:6px; padding:.1rem .45rem; font-weight:700;
  color:var(--primary-ink); font-size:.94em; white-space:nowrap; }

/* --- S12 map frame ------------------------------------------ */
.loc-map iframe{ display:block; width:100%; height:100%; min-height:360px; border:0; }

/* --- S13 small things --------------------------------------- */
.hl-list{ margin-top:2.4rem; display:grid; gap:1.6rem; grid-template-columns:repeat(2,1fr); }
.hl-list .hl{ background:var(--card); border:1px solid var(--rule); border-radius:var(--radius);
  overflow:hidden; box-shadow:var(--shadow-sm); display:flex; flex-direction:column; }
.hl-grid .hl{ display:flex; flex-direction:column; }
.hl-list .hl .hl-img{ aspect-ratio:16/10; position:relative; }
.hl .hl-img .ph{ position:absolute; inset:0; }
.hl-list .hl .hl-body{ padding:1.5rem 1.7rem 1.8rem; }
.hl-list .hl.lead{ grid-column:1 / -1; display:grid; grid-template-columns:1.02fr .98fr; }
.hl-list .hl.lead .hl-img{ aspect-ratio:auto; min-height:22rem; }
.hl-list .hl.lead .hl-body{ padding:clamp(1.8rem,3vw,2.8rem); align-self:center; }
.hl-list .hl.lead h3{ font-size:clamp(1.5rem,2.4vw,2rem); }
.hl-list .hl h3{ font-size:1.32rem; }
.hl-list .hl p{ margin-top:.65rem; color:var(--ink-soft); font-size:1rem; }
@media (max-width:900px){ .hl-list{ grid-template-columns:1fr; }
  .hl-list .hl.lead{ grid-template-columns:1fr; }
  .hl-list .hl.lead .hl-img{ min-height:0; aspect-ratio:16/10; } }
.pill-row{ display:flex; flex-wrap:wrap; gap:.55rem; margin-top:1.3rem; }
.pill{ background:var(--card); border:1px solid var(--rule); border-radius:999px; padding:.45rem 1rem;
  font-size:.88rem; font-weight:700; color:var(--ink); }
.band-deep .pill{ background:rgba(255,255,255,.1); border-color:rgba(255,255,255,.24); color:#fff; }
.homelink{ display:inline-flex; align-items:center; gap:.4rem; font-weight:800; color:var(--sea-ink);
  text-decoration:underline; text-underline-offset:3px; }
.say a{ color:var(--sea-ink); font-weight:700; text-decoration:underline; text-underline-offset:2px; }
.care-foot a,.localline a{ color:var(--sea-ink); }
.foot .credit a{ text-decoration:underline; text-underline-offset:3px; }
.twocol{ columns:2; column-gap:clamp(2rem,4vw,3.4rem); }
@media (max-width:820px){ .twocol{ columns:1; } }

/* --- S14 placeholder plumbing ------------------------------
   The Elm placeholder convention is a NESTED .ph filling its slot.
   The inherited list of slots predates several of the components
   this build added, so extend it rather than fork it. PROMOTE. */
.pc-photo, .g-img, .tl-photo, .p-photo, .fr-photo, .home-img, .hl-list .hl-img{ position:relative; }
.pc-photo > .ph, .g-img > .ph, .tl-photo > .ph, .p-photo > .ph,
.fr-photo > .ph, .home-img > .ph, .hl-list .hl-img > .ph{ position:absolute; inset:0; }
/* The hero brand field is not a placeholder and must not carry a label strip. */
.hero .bg .brandfield::before{ content:none; }

/* --- S15 hero, left variant, corrections -------------------
   N3 retired the N-series build's .left hero and centred the gold rule
   with margin:0 auto. The engine's D1 IS left-aligned, so the rule
   has to start at the text edge again. */
.hero.left .gold-rule{ margin-inline:0; width:74px; height:3px; background:var(--primary); }
.hero.left .inner{ padding-top:6.5rem; padding-bottom:4rem; }
@media (max-width:900px){ .hero.left .inner{ padding-bottom:1.5rem; } }

/* --- S16 placeholders that look deliberate ------------------
   This build ships with no client photography at all, so the
   placeholder is not a rare gap-filler, it is a component people
   will look at. Give it a warm brand field, a quiet photograph
   glyph, and the same label strip as before, so a slot reads as
   "a photograph belongs here" rather than as a broken image.
   PROMOTE: the plain two-tint gradient was too faint to read. */
.ph{ background-color:var(--band-tint);
  background-image:
    radial-gradient(ellipse 70% 70% at 30% 22%, var(--ph-bloom) 0%, var(--ph-bloom-0) 62%),
    linear-gradient(150deg, var(--band-tint) 0%, var(--accent-tint) 100%); }
.ph::after{ content:""; position:absolute; left:50%; top:50%; width:clamp(30px,14%,54px);
  aspect-ratio:1; transform:translate(-50%,-60%); opacity:.34; pointer-events:none;
  background:var(--primary-ink);
  -webkit-mask:var(--ph-glyph) center/contain no-repeat; mask:var(--ph-glyph) center/contain no-repeat; }
:root{ --ph-glyph:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.6h3.2l1.4-2.2h8.8l1.4 2.2H21v10.2H3Z'/%3E%3Ccircle cx='12' cy='13.4' r='3.6'/%3E%3C/svg%3E"); }
.hero .bg .ph::after{ display:none; }

/* On a home card the strip would run straight through the home's
   name, so the marker becomes a small pill in the free corner. */
/* The label must clear the card's own furniture: the badge sits top-left and the
   name block runs along the bottom, so the only free corner is top-right. It sat
   bottom-right until this build, where it printed straight through the home's
   name. PROMOTE UPSTREAM. */
.home-card .ph::before{ left:auto; right:.9rem; top:.9rem; bottom:auto; height:auto; width:auto;
  max-width:46%; line-height:1.45; padding:.34rem .8rem; border-radius:999px; font-size:.62rem;
  text-align:right; white-space:normal; background:rgba(250,247,241,.92); }
.home-card .ph::after{ transform:translate(-50%,-90%); }

/* --- S17 the ask list carries plain spans on this build ----- */
.asks .ask > svg{ flex:none; color:var(--primary); margin-top:.22rem; }
.asks .ask > span{ color:var(--ink-soft); font-size:1rem; }

/* --- S18 the cookie notice must not sit on top of a button ---
   It is fixed to the bottom centre, which is exactly where a form's
   submit button ends up on a long page: measured on contact.html,
   the notice covered #enqBtn and the button could not be clicked
   until it was dismissed. Reserve the space while it is up.
   PROMOTE: every build in the library has this fault. */
/* Round 3 (Jon, 1 Oct 2026: "a weird gap at the bottom below the footer"): the space
   was padding on <body>, so it showed as a strip of paper under the dark footer. It now
   lives INSIDE the footer's legal row, sized to the notice's measured height, so the
   footer simply runs a little deeper while the notice is up and nothing shows below it.
   Once the notice is dismissed the extra depth goes with it. */
html.cookie-up .foot-legal{ padding-bottom:calc(var(--cookie-h, 7rem) + 1.75rem); }

/* --- S19 the consent checkbox has to respond to being clicked --
   The inherited markup wraps the input in <label class="consent"
   for="f-consent">. Because the label is BOTH the ancestor and an
   explicit label, a click on the box itself toggles once for the
   input and once for the label, and lands back where it started:
   measured, a direct click on the box did nothing at all. The
   markup fix is to drop the redundant for= and rely on the
   implicit association, which is what the pages now do. This rule
   only widens the target, since this audience is older and less
   dexterous. PROMOTE UPSTREAM: Gratwick and the N-series build ship the
   same double-toggling markup. */
.consent{ cursor:pointer; padding:.35rem 0; }
.consent input{ width:22px; height:22px; }

/* --- S20 phone-width fixes found by measuring at 390 ---------
   Two real overflows, both invisible behind body{overflow-x:hidden}
   until scrollWidth was compared with clientWidth.
   1. The fees tables pushed the page to 612px wide at a 390px
      viewport. They now scroll inside their own container, with a
      hint so nobody has to guess, and the type tightens.
   2. The [to confirm] markers were white-space:nowrap, and one of
      them is a whole sentence, which pushed privacy.html to 421px.
      They wrap now; the marker still reads as a marker. PROMOTE. */
.feecap{ margin-top:.9rem; font-size:.92rem; color:var(--ink-soft); max-width:60ch; }
.feewrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; margin-top:.9rem; }
.feetable{ margin-top:0; }
.feetable caption{ display:none; }
@media (max-width:600px){
  .feetable th,.feetable td{ padding:.75rem .8rem; font-size:.95rem; }
  .feetable th{ font-size:.75rem; letter-spacing:.03em; }
}
@media (max-width:400px){
  .feetable th,.feetable td{ padding:.7rem .6rem; font-size:.9rem; }
}
.todo{ white-space:normal; }

/* --- S21 tap targets in the nav ------------------------------
   Measured at 29px tall. This audience is older and less
   dexterous, so the hit area is padded to 44px without changing
   how the bar looks. PROMOTE. */
/* Direct children only. As a descendant selector this also caught the links inside
   the "Our Homes" dropdown panel, turning each into an inline-flex row so the town
   label sat beside the home name instead of under it. */
.navlinks > a:not(.btn){ display:inline-flex; align-items:center; min-height:44px; }
/* the dropdown links keep the same 44px hit area, stacked rather than in a row */
.navdrop-m a{ min-height:44px; }
.foot a{ padding-block:.45rem; margin-bottom:0; }
.consent{ min-height:44px; align-items:center; }
.teamlead blockquote{ margin-bottom:1.3rem; }

/* ============================================================
   ROUND 1 (Jon's review, 13 Aug 2026)
   ============================================================ */

/* --- R1.4 anchor landing -----------------------------------
   The generic [id] offset (156px) is right for bare elements but
   wrong for a whole <section>, which carries its own top padding
   (var(--sp), 119px at 1536). "See our homes" therefore landed the
   reader on 145px of empty band with the home cards below the fold.
   Anchored sections now pull themselves up by their own padding, so
   the section's gold rule sits just under the fixed nav (measured
   nav height: 100px scrolled at 1536, 82px at 390). */
section.section[id]{ scroll-margin-top:calc(124px - var(--sp)); }
section.section.snug[id]{ scroll-margin-top:calc(124px - (var(--sp) * .68)); }
@media (max-width:1040px){
  section.section[id]{ scroll-margin-top:calc(104px - var(--sp)); }
  section.section.snug[id]{ scroll-margin-top:calc(104px - (var(--sp) * .68)); }
}

/* --- R1.5 the cookie notice must not sit on top of the hero CTA ------
   S18 reserved space at the END of the document, which fixes long forms
   but does nothing for a full-height hero at the top: measured at 390px,
   the notice covered "Arrange a visit" and the hero phone line outright.
   script.js publishes the notice's real height as --cookie-h; the hero's
   centred content is lifted clear of it while the notice is up. Desktop
   is unaffected, the notice sits well below the hero content there.
   PROMOTE: every build in the library has this fault. */
@media (max-width:760px){
  /* padding-top still has to clear the fixed nav (measured 88px at 390): an
     earlier pass cut it to 1.2rem and the eyebrow slid under the wordmark. */
  html.cookie-up .hero .inner{ padding-top:5.4rem; padding-bottom:calc(2 * (var(--cookie-h, 0px) + 2rem)); }
  /* The home hero carries the most content of any (two CTAs and two phone
     numbers), so its rhythm is tightened while the notice is up. */
  html.cookie-up .hero h1{ margin-top:.6rem; }
  html.cookie-up .hero .sub{ margin-top:.9rem; }
  html.cookie-up .hero .cta-row{ margin-top:1.4rem; }
  html.cookie-up .hero .hero-tel{ margin-top:.9rem; }
}

/* --- R1.7 the cookie notice is compact on a phone -------------------
   At 390 it stood 169px tall, which with the fixed nav left too little
   room for a hero to sit between them. Same words, smaller frame. */
@media (max-width:520px){
  .cookie{ padding:.75rem .85rem; gap:.7rem; font-size:.84rem; bottom:.65rem; left:.65rem; right:.65rem; }
  .cookie p{ font-size:.84rem; line-height:1.45; }
  .cookie button{ padding:.5rem .9rem; font-size:.85rem; }
}

/* ------------------------------------------------------------------
   FOOTER REBUILD (Jon, round 3, 13 Aug 2026: "looks like word spaghetti")
   The fault was that every line in a column had the same weight, size and
   colour, so a service list, a postal address, two contact links and a
   navigation list all ran together as one grey block. The fix is hierarchy,
   not more space: the service line is small and muted, the address is set
   as an address at a comfortable measure, the phone and email are the
   brightest thing in the column because they are the useful thing, and the
   page links sit below a hairline so they read as a separate group. The
   Explore list goes two-up so the footer stops being a tall ladder.
   PROMOTE UPSTREAM: this replaces the flat .fcol treatment library-wide.
------------------------------------------------------------------- */
.foot .cols{ grid-template-columns:1.15fr 1fr 1fr 1.1fr; gap:2.6rem; }
.foot .fcol{ min-width:0; }

/* Fixed two-line box so both home columns start their address, phone and
   hairline on the same line, whether the service list wraps or not. Same
   trick as the dense-row headings in the gratwick-standard. */
.foot .fserv{
  display:block; font-size:.82rem; line-height:1.5; letter-spacing:.02em;
  color:rgba(255,255,255,.58); margin-bottom:.55rem;
  min-height:3em;   /* exactly two lines at line-height 1.5 */
}
.foot address{
  font-style:normal; font-size:.95rem; line-height:1.65;
  color:rgba(255,255,255,.74); margin-bottom:.9rem; max-width:22ch;
  min-height:4.95em;  /* three lines at line-height 1.65. Both home addresses are
                         set on three lines in the markup (street / town / postcode)
                         so neither wraps at any width and the phone, email and
                         hairline below start on the same line in both columns. */
}
/* The two things a worried family actually reaches for. */
.foot a.fkey{
  display:block; color:#fff; font-weight:600; font-size:.98rem;
  margin-bottom:.3rem; word-break:break-word;
}
.foot a.fkey:last-of-type{ font-weight:500; color:rgba(255,255,255,.9); font-size:.92rem; }

/* Page links, set apart from the contact block by a hairline. */
.foot .fmore{
  display:block; margin-top:1rem; padding-top:.9rem;
  border-top:1px solid rgba(255,255,255,.13);
}
.foot .fmore a{
  font-size:.9rem; color:rgba(255,255,255,.72); margin-bottom:.35rem;
}
.foot .fmore a:hover{ color:#fff; }

.foot .fnav{ display:grid; grid-template-columns:1fr 1fr; gap:0 1.4rem; }
.foot .fnav a{ font-size:.92rem; margin-bottom:.5rem; }

@media (max-width:1040px){
  .foot .cols{ grid-template-columns:1fr 1fr; gap:2.2rem; }
}
@media (max-width:560px){
  .foot .cols{ grid-template-columns:1fr; gap:2rem; }
  .foot address{ max-width:none; }
  .foot .fnav{ gap:0 1rem; }
}

/* ------------------------------------------------------------------
   ROUND 4 FIXES (Jon, 13 Aug 2026)
------------------------------------------------------------------- */

/* 1. Four-value grids. Three columns stranded the fourth card on its own row
      (Our Values, About + Meet the Team). Four across on wide, 2x2 on tablet. */
.values-grid.four{ grid-template-columns:repeat(4,1fr); }
@media (max-width:1180px){ .values-grid.four{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:560px){ .values-grid.four{ grid-template-columns:1fr; } }

/* 2. The Q&A blocks read as broken because .faq is centred (max-width 820, auto
      margins) while its heading above stayed left-aligned, so the two sat on
      different axes with a large empty gutter. The heading now carries .center
      in the markup; this keeps the measure identical so they line up exactly. */
.section-head.center + .acc.faq,
.section-head.center ~ .acc.faq{ max-width:820px; margin-inline:auto; }
.acc.faq .acc-head{ text-align:left; }

/* 3. Care accordion: the copy column must not outgrow the sticky photograph, or
      an expanded item pushes the page down past it (Jon: "never goes below the
      bottom"). The photo is given a taller frame and the open body is capped and
      scrolls internally in the rare case a long answer still overflows.

      SCOPED TO DESKTOP on 6 Sep 2026. This 3/4 was written for the two-column
      desktop layout, but it was declared unscoped and at two-class specificity,
      so it also beat the library's `@media (max-width:900px){ .ca-photo{
      aspect-ratio:16/10 } }` and governed the PHONE, where the photograph is a
      full-width band. Measured at 900px: a 713px-wide picture 950px tall, which
      is most of a screen of scrolling before the panels even start. On desktop
      it is moot anyway, because rule 14 below sets an explicit height. */
@media (min-width:901px){ .care-accordion .ca-photo{ aspect-ratio:3/4; } }
.care-accordion .acc-body-inner{ max-height:none; }
@media (min-width:901px){
  .care-accordion .acc{ max-height:none; }
  .care-accordion .acc-body[style*="block"] .acc-body-inner,
  .care-accordion .acc-body-inner{ overflow:hidden; }
}


/* 5. Elaine's section. Two long grey paragraphs either side of a quote gave the
      column no rhythm against a tall portrait. Now: name, role line, a short
      opening, the quote with real presence, then three labelled points that
      carry the practical detail and align to the bottom of the photograph. */
.teamlead .tl-role{
  display:block; font-family:var(--body); font-weight:700; font-size:.82rem;
  letter-spacing:.12em; text-transform:uppercase; color:var(--gold-ink);
  margin:-.2rem 0 1.1rem;
}
.teamlead blockquote{ font-size:clamp(1.15rem,1.7vw,1.42rem); line-height:1.5; }
.tl-points{ display:grid; gap:1.1rem; margin-top:1.6rem; }
.tl-points > div{
  display:grid; gap:.25rem; padding-left:1.1rem; position:relative;
  border-left:2px solid var(--rule);
}
.tl-points b{ font-family:var(--body); font-weight:800; font-size:.98rem; color:var(--ink); }
.tl-points span{ color:var(--ink-soft); font-size:.98rem; line-height:1.6; }

/* 6. "Join us" was a full-width centred heading over a centred button, which is
      exactly the shape of the CTA section directly beneath it, so the page ended
      with the same gesture twice. It is now a slim aside: copy left, button
      right, quiet border, no heading competing with the CTA below. */
.joinband{
  display:flex; align-items:center; justify-content:space-between; gap:1.6rem 2rem;
  flex-wrap:wrap; padding:1.6rem 1.9rem;
  border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--card);
}
.joinband .jb-copy{ max-width:62ch; }
.joinband .eyebrow{ margin-bottom:.4rem; }
.joinband p{ color:var(--ink-soft); font-size:1rem; line-height:1.6; margin:0; }
@media (max-width:640px){ .joinband{ padding:1.4rem 1.3rem; } .joinband .btn{ width:100%; text-align:center; } }

/* 7. The About timeline. The About page was repeating the home page's two-homes
      cards and the team page's values, so it had no spine of its own (Jon, round
      4). The family's twenty years is material no other page carries, and a
      dated rail is the shape that suits it: a hairline runs down the years, each
      year sits in a fixed-width column so every entry starts level, and the
      marker dot sits ON the rule rather than near it (measured, not eyeballed). */
.tline{ list-style:none; margin:2.8rem auto 0; padding:0; max-width:860px; }
.tline li{
  display:grid; grid-template-columns:104px 1fr; gap:0 1.9rem;
  position:relative; padding-bottom:2.2rem;
}
.tline li:last-child{ padding-bottom:0; }
/* the rail, drawn from the centre of the marker so the two always agree */
.tline li::before{
  content:""; position:absolute; left:117px; top:1.55rem; bottom:-.35rem;
  width:2px; background:var(--rule);
}
.tline li:last-child::before{ display:none; }
.tline li::after{
  content:""; position:absolute; left:112px; top:.62rem;
  width:12px; height:12px; border-radius:50%;
  background:var(--cta); box-shadow:0 0 0 4px var(--surface);
}
.tline .ty{
  font-family:var(--display); font-weight:600; font-size:1.42rem;
  color:var(--gold-ink); line-height:1.2; padding-top:.1rem; text-align:right;
}
.tline .tb h3{ font-size:1.24rem; margin-bottom:.4rem; }
.tline .tb p{ color:var(--ink-soft); font-size:1rem; line-height:1.65; margin:0; }
@media (max-width:640px){
  .tline li{ grid-template-columns:1fr; gap:.35rem; padding-left:1.5rem; padding-bottom:1.9rem; }
  .tline li::before{ left:4px; top:1.7rem; }
  .tline li::after{ left:0; top:.75rem; }
  .tline .ty{ text-align:left; font-size:1.2rem; }
}

/* 8. Contact page density (Jon, round 4: "feels a little too large for the page
      and requires quite a lot of scroll"). The page was not long, it was loose:
      full section rhythm, a deeply padded enquiry card and generous field gaps
      on a page whose whole job is one form. Scoped to the contact page so the
      rest of the site keeps its breathing room. The home selector, which Jon
      likes, is untouched apart from sitting a little tighter. */
body.p-contact main .section{ padding-block:clamp(3rem,5.2vw,4.4rem); }

body.p-contact .field{ margin-bottom:.95rem; }
body.p-contact .field-row{ gap:1rem; }
body.p-contact .field textarea{ min-height:104px; }
body.p-contact .step-hint{ margin-bottom:.7rem; }
body.p-contact .home-select{ gap:.75rem; margin-bottom:1.4rem; }
body.p-contact .enq-banner{ margin-bottom:1.1rem; padding:.7rem 1rem; }
body.p-contact .section-head{ margin-bottom:.2rem; }
body.p-contact .ccard{ padding:1.3rem 1.4rem; }

/* 9. The enquiry form as a CALLOUT (Jon, round 5, pointing at the Gratwick
      contact page). Two things were wrong. The card carried a 1px outline, which
      pins it flat to the page instead of letting it float, and the round-4
      compaction had squeezed its padding, so it read as a cramped box rather
      than a generous callout. Gratwick's card is border-free, deeply padded and
      lifted on the standard shadow: that is the register. Page density is kept
      by tightening the space AROUND the card, never the card itself. */
.enquiry{
  padding:clamp(1.9rem,3.2vw,3.1rem);
  border-radius:calc(var(--radius) + 4px);
  box-shadow:0 44px 90px -54px rgba(var(--shadow-rgb),.55),
             0 6px 18px -12px rgba(var(--shadow-rgb),.22);
}
/* the callout lifts slightly into the space above it, which is what makes it
   read as sitting ON the page rather than in the flow of it */
body.p-contact .contact-grid{ margin-top:2rem; }
body.p-contact .contact-aside{ padding-top:.4rem; }
/* aside cards stay quieter than the callout so the form is clearly the subject */
body.p-contact .ccard{ box-shadow:var(--shadow-sm); }

/* Grid children default to min-width:auto, so an unbreakable child (a long email
   address, or a padded card) can force its track wider than the container. With
   the callout's larger padding this pushed the contact page 9px past 390. Letting
   the tracks shrink, and allowing the long addresses to wrap, fixes it at source. */
.contact-grid > *{ min-width:0; }
.contact-aside a, .contact-aside .crow span{ overflow-wrap:anywhere; }
@media (max-width:560px){
  .enquiry{ padding:clamp(1.15rem,4.4vw,1.6rem); border-radius:var(--radius); }
}

/* ------------------------------------------------------------------
   ROUND 6 (Jon, 13 Aug 2026)
------------------------------------------------------------------- */

/* 10. "Our Homes" nav dropdown, which replaces the retired About link. Opens on
       hover for mice and on click/focus for keyboards and touch, and closes on
       Escape or outside click (script.js). The panel is padded above so the
       pointer can travel from the trigger into it without the menu closing. */
.navdrop{ position:relative; display:flex; align-items:center; }
.navdrop-t{
  display:inline-flex; align-items:center; gap:.42rem;
  font-family:var(--body); font-weight:700; font-size:1rem;
  color:rgba(255,255,255,.92); background:none; border:0; padding:0; cursor:pointer;
  white-space:nowrap; transition:color .3s;
}
.navdrop-t:hover, .navdrop.open .navdrop-t{ color:#fff; }
.navdrop-t svg{ transition:transform .25s var(--ease); }
.navdrop.open .navdrop-t svg{ transform:rotate(180deg); }
.navdrop-m{
  position:absolute; top:100%; left:50%; transform:translate(-50%,6px);
  margin-top:14px; min-width:268px; background:var(--card);
  border-radius:var(--radius-sm); box-shadow:0 30px 60px -30px rgba(var(--shadow-rgb),.45);
  padding:.5rem; opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .22s var(--ease), transform .22s var(--ease), visibility .22s;
  z-index:60;
}
/* the invisible bridge: without it the menu closes as the pointer crosses the gap */
.navdrop-m::before{ content:""; position:absolute; left:0; right:0; top:-16px; height:16px; }
.navdrop:hover .navdrop-m, .navdrop.open .navdrop-m{
  opacity:1; visibility:visible; pointer-events:auto; transform:translate(-50%,0);
}
.navdrop-m a{
  display:block; padding:.72rem .9rem; border-radius:10px;
  color:var(--ink); font-weight:400;
}
.navdrop-m a:hover, .navdrop-m a:focus-visible{ background:var(--band-tint); color:var(--ink); }
.navdrop-m a b{ display:block; font-family:var(--display); font-weight:600; font-size:1.06rem; color:var(--ink); }
.navdrop-m a span{ display:block; font-size:.83rem; letter-spacing:.1em; text-transform:uppercase; color:var(--primary-ink); margin-top:.12rem; }
/* The nav repaints on scroll. Two class names do it in this library, .scrolled
   (set by script.js) and .solid (used by pages with no hero behind the bar), and
   the first version of this rule only covered .solid, so on scroll the trigger
   stayed white-on-cream and vanished. Both states are handled here. */
.nav.scrolled .navdrop-t, .nav.solid .navdrop-t{ color:var(--ink); }
.nav.scrolled .navdrop-t:hover, .nav.solid .navdrop-t:hover,
.nav.scrolled .navdrop.open .navdrop-t, .nav.solid .navdrop.open .navdrop-t{ color:var(--primary-ink); }
@media (max-width:1040px){ .navdrop{ display:none; } }

/* 11. Our Care: the photograph now matches the accordion exactly, so the bottom
       edges are level whichever panel is open (Jon, round 6: "should just extend
       to the bottom of the extended drop down"). Stretching the row and letting
       the photo fill it does this by construction, with no fixed aspect ratio to
       drift out of step. Sticky is dropped: a sticky element cannot also be the
       thing whose height is being matched. */
@media (min-width:901px){
  .care-accordion{ align-items:stretch; }
  .care-accordion .ca-photo{
    position:relative; top:auto; height:100%; aspect-ratio:auto; min-height:0;
  }
}

/* 12. Our Care needed more places for real photographs (Jon, round 6). This strip
       sits under the day-in-the-life steps and gives three captioned slots that
       follow the arc of a day, so a phone-photo pass has somewhere obvious to land. */
.daystrip{ display:grid; grid-template-columns:repeat(3,1fr); gap:1.2rem; margin-top:2.4rem; }
.daystrip figure{ margin:0; }
.daystrip .ds-img{ position:relative; aspect-ratio:4/3; border-radius:var(--radius-sm);
  overflow:hidden; box-shadow:var(--shadow-sm); }
.daystrip .ds-img .ph{ position:absolute; inset:0; }
.daystrip figcaption{ margin-top:.6rem; font-size:.88rem; color:var(--ink-soft); }
@media (max-width:820px){ .daystrip{ grid-template-columns:1fr 1fr; } .daystrip figure:last-child{ display:none; } }
@media (max-width:520px){ .daystrip{ grid-template-columns:1fr; } .daystrip figure:last-child{ display:block; } }

/* 13. Footer home columns sized as one (Jon, round 6). The service line was already
       boxed to two lines; the address needed the same so the two home columns match
       depth for depth, and both columns share a single grid row so their cards and
       links start and end level whatever the content length. */
.foot .cols{ align-items:start; }
.foot .fcol{ display:flex; flex-direction:column; }
.foot .fcol .fmore{ margin-top:auto; }

/* ------------------------------------------------------------------
   ROUND 7 (Jon, 13 Aug 2026)
------------------------------------------------------------------- */

/* 14. Care accordion, revised. Round 6 stretched the photograph to match the copy
       column, which kept the bottoms level but meant the picture changed size every
       time a panel opened. Jon now wants the IMAGE ITSELF to stay one size, while
       still honouring the earlier rule that an open panel never runs past the bottom
       of it. Both hold at once only if the photo is a FIXED height and the copy
       column is capped to that same height, so the tallest panel is the constraint
       rather than the outcome. The cap is generous enough that no current panel
       reaches it (measured: tallest is 614px against a 640px frame). */
@media (min-width:901px){
  .care-accordion{ align-items:start; }
  .care-accordion .ca-photo{
    position:sticky; top:110px;
    height:var(--ca-frame); aspect-ratio:auto; min-height:0;
  }
  /* The cap is gated on html.reveal-ready, and it has to be. The cap only makes
     sense while script.js is running, because that is what keeps exactly one
     panel open. With JavaScript off, every panel is open by design (see the
     .acc-body rules further up, which is the honest fallback) and the column
     needs 1855px - so a flat cap hid 1130px of it, four and a half of the six
     kinds of care, behind overflow:hidden. Measured with JS off AND with
     script.js blocked; both were silently broken.
     reveal-ready is set by the inline head script and dropped again after 2.5s
     if script.js never boots, so the cap applies in exactly the case it was
     written for and in no other. PROMOTE UPSTREAM: this is inherited, so every
     build carrying the care accordion has the same hole. */
  html.reveal-ready .care-accordion .acc{ max-height:var(--ca-frame); overflow:hidden; }
}
/* THE FRAME HEIGHT IS A VARIABLE NOW, and 640 was not enough here.
   640px is calibrated for FIVE panels, which is what Gratwick, Stanley Lodge and
   the N-series build all carry. This client has six, and a sixth closed head costs 78px,
   so the column needs 712px for its tallest panel. At 640 the cap silently
   clipped FIVE of the six panels with overflow:hidden - measured, and it would
   have shipped invisibly, because a clipped accordion looks exactly like a short
   one. The construction is unchanged and Jon's round 7 rule still holds: the
   picture is one fixed size and the panel column is capped to that same size, so
   no panel ever runs past the bottom of the photograph. Only the number moved.
   730 = 468 (six heads) + 244 (the tallest body) + 18 headroom for a copy edit.
   IF A PANEL IS ADDED OR ITS COPY GROWS, RE-MEASURE THIS. tools: cap.js. */
:root{ --ca-frame:730px; }

/* 15. Review slider. REMOVED, 7 Sep 2026. This build carried the component
   TWICE: once here and again as Y11.4 below, which is later in the file and
   therefore the one that was actually rendering. Two copies of a component
   is how a fix gets made in the half nobody is looking at - which is exactly
   what happened this round. The single definition is Y11.4. */

/* ============================================================
   Y. TWO-HOME LIBRARY LAYER (inherited 2 Sep - 7 Sep 2026, signed off)
   The previous two-home build's layer, kept wherever a rule is really a
   library fix (home cards, the photoless hero field, highlight cards,
   heading balance, the italic-word colour). Its own brand rules (a
   capitals-only brand face, the display-size lift that face needed, and its
   traced sign mark) were removed on clone: Lora is tuned to the library's
   own heading sizes, so no lift is needed here. Client-specific rules for
   this build live in the AO block at the foot of this file.
   ============================================================ */

/* --- Y1 the italic-word move ----------------------------------
   The library sets .serif as the italic word in a heading. On light bands it
   takes the copper ink; over the hero field it takes --accent-on-photo. */
.hero h1 .serif,.about-copy h2 .serif,.section-head h2 .serif,.fr-copy h2 .serif,.cta h2 .serif{ font-style:italic; }
.about-copy h2 .serif,.section-head h2 .serif,.fr-copy h2 .serif{ color:var(--primary-ink); }

/* --- Y4 the mark as a section ornament ------------------------ */
.section-head.center .eyebrow{ display:block; }
.sprig-rule{ display:block; width:46px; height:auto; margin:0 auto 1rem; color:var(--primary); }
.foot .fsprig{ display:block; width:46px; margin-bottom:.9rem; color:var(--accent-soft); }
.foot .fsprig svg{ width:100%; height:auto; display:block; }

/* --- Y5 hero field variants -----------------------------------
   Each page's field puts its blooms somewhere different, so the heroes are
   recognisably one system without being the same picture seven times. */
.brandfield.f2::before{ background:
  radial-gradient(ellipse 56% 60% at 18% 26%, var(--field-bloom-a) 0%, var(--field-bloom-a0) 66%),
  radial-gradient(ellipse 60% 64% at 88% 82%, var(--field-bloom-b) 0%, var(--field-bloom-b0) 70%); }
.brandfield.f3::before{ background:
  radial-gradient(ellipse 62% 52% at 50% 12%, var(--field-bloom-a) 0%, var(--field-bloom-a0) 70%),
  radial-gradient(ellipse 54% 62% at 16% 92%, var(--field-bloom-b) 0%, var(--field-bloom-b0) 68%); }
.brandfield.f4::before{ background:
  radial-gradient(ellipse 50% 56% at 84% 30%, var(--field-bloom-a) 0%, var(--field-bloom-a0) 64%),
  radial-gradient(ellipse 70% 60% at 30% 96%, var(--field-bloom-b) 0%, var(--field-bloom-b0) 72%); }
.brandfield .arc{ right:-18%; bottom:-46%; opacity:.16; }
.brandfield .arc2{ left:-30%; top:-42%; opacity:.10; }
/* The field needs to be a designed surface, not a dark rectangle: the mark sits
   in it at a size nobody would call an icon, cropped by the frame the way a
   watermark is, with the blooms lifting the ground around it. */
.brandfield .fieldmark{ position:absolute; right:4%; top:50%; width:min(34vw,440px);
  transform:translateY(-52%); color:var(--primary); opacity:.30; }
.brandfield .fieldmark svg{ width:100%; height:auto; display:block; }
.brandfield.f2 .fieldmark{ right:auto; left:58%; top:40%; width:min(30vw,400px); opacity:.26; }
.brandfield.f3 .fieldmark{ right:7%; top:46%; width:min(28vw,380px); opacity:.28; }
.brandfield.f4 .fieldmark{ right:auto; left:60%; top:58%; width:min(30vw,400px); opacity:.24; }
@media (max-width:760px){ .brandfield .fieldmark,.brandfield.f2 .fieldmark,.brandfield.f3 .fieldmark,.brandfield.f4 .fieldmark{
  width:62vw; left:auto; right:-14%; top:auto; bottom:4%; transform:none; opacity:.16; } }

/* --- Y6 small things ------------------------------------------ */
.cta .ctatels{ margin-top:1.1rem; }
.section-head .say{ margin-top:1.05rem; }

/* --- Y7 home cards ------------------------------------------
   Hover or focus the picture and the description rises out of the scrim.
   Below 1000px there is no reliable hover, so Y9 turns the card into a
   picture with a caption underneath instead. */
.homes-grid.two .home-card{ aspect-ratio:4/3.1; }
/* Between 1001 and 1400 the two cards are narrow enough that the revealed label
   (badge, place, name, description, button) is TALLER than a 4/3.1 card and was
   clipped at the top. aspect-ratio has to be turned OFF to floor it, not just
   floored: with a min-height AND a ratio, the ratio resolves the other way and
   computes the WIDTH from the height, which pushed both cards out of their grid
   columns. Above 1400 the ratio already gives more than the floor and takes back
   over on its own. The floor is re-measured for THIS build's copy in AO. */
@media (min-width:1001px) and (max-width:1400px){
  .homes-grid.two .home-card{ aspect-ratio:auto; min-height:25.5rem; } }
.home-card .label .more p{ max-width:44ch; }
@media (max-width:1000px) and (min-width:561px){ .home-card .label .more p{ max-width:58ch; } }
/* Resting scrim: light enough to show the photograph, dark enough to carry the
   place label and the home's name. Measured by pixel sweep on the last build. */
.home-card .scrim{ background:linear-gradient(180deg, rgba(var(--shadow-rgb),0) 24%, rgba(var(--shadow-rgb),.40) 52%, rgba(var(--shadow-rgb),.80) 72%, rgba(var(--shadow-rgb),.94) 100%); }
/* The HOVER scrim is much stronger than instinct suggests, and it has to be: the
   revealed paragraph is body text over the middle of the photograph, so it needs
   4.5:1 against a bright sky. White on a sky of about rgb 235 needs an alpha of
   0.61 before it reaches 4.5:1, so the ramp is at 0.74 by the top quarter. */
.home-card:hover .scrim,.home-card:focus-within .scrim{ background:linear-gradient(180deg, rgba(var(--shadow-rgb),.42) 0%, rgba(var(--shadow-rgb),.76) 24%, rgba(var(--shadow-rgb),.90) 58%, rgba(var(--shadow-rgb),.96) 100%); }
.home-card .label .more{ transition:max-height .55s var(--ease), opacity .4s var(--ease) .05s, margin-top .55s var(--ease); }
/* A device with no hover cannot perform the reveal, and width is a poor proxy for
   that: an iPad in landscape is 1024px wide with no pointer at all. */
@media (hover:none){ .home-card .label .more{ max-height:340px; opacity:1; margin-top:.9rem; } }
/* While the safety-net keyframe is fading the veil out (a session where script.js
   never booted) the element still sits over the page and swallows clicks. */
.loader{ pointer-events:none; }
.loader .lmark{ pointer-events:auto; }

/* --- Y8 highlight cards ------------------------------------ */
@media (min-width:901px){ .hl-list .hl.lead .hl-img{ min-height:19rem; } }
.hl .hl-img .ph::after{ width:clamp(24px,9%,34px); }

/* --- Y9 home cards below 1000px ------------------------------
   With the description always visible the label, absolutely positioned against
   the bottom of a fixed-ratio card, grew taller than the card and was clipped.
   On small screens the card becomes a picture with a caption under it: the
   image is a band, the label is in normal flow beneath it, and the card grows
   to fit its own content. */
@media (max-width:1000px){
  .homes-grid.two .home-card{ aspect-ratio:auto; min-height:0;
    display:grid; grid-template-rows:clamp(13rem,34vw,20rem) auto; background:var(--primary-deep); }
  .home-card .home-img{ position:relative; inset:auto; grid-row:1; overflow:hidden; }
  .home-card .scrim{ display:none; }
  .home-card .label{ position:static; grid-row:2; padding:1.4rem 1.4rem 1.7rem; }
  .home-card .label h3{ font-size:1.55rem; }
  .home-card .ph::after{ top:50%; }
}

/* --- Y10 no orphaned words in headings -----------------------
   text-wrap:balance evens the lines out and keeps working when the client edits
   the copy. It degrades to normal wrapping where it is unsupported. */
h1,h2,h3,.section-head .say,.hero .sub{ text-wrap:balance; }

/* ============================================================
   Y11  ROUND 3 (6 September 2026, Jon's list)
   ============================================================ */

/* --- Y11.1 page transitions ----------------------------------
   Jon: "needs to be a softer transition between loading / going between pages."
   Two halves, and they have to agree with each other or the site flickers.

   IN  - every page fades and settles up 8px on arrival. Opacity and transform
         only, so it composites and never relays the page. The first-load veil
         already sits over this, so on a first visit the two read as one move.
   OUT - script.js adds .leaving to <html> when an internal link is clicked and
         holds the navigation for the length of this fade. 260ms: long enough to
         read as a transition, short enough that nobody waits for it.

   THE FAILURE MODE this is written around: if the fade-in is gated on JavaScript
   and the script never boots, the page sits at opacity 0 and the site is blank.
   So the fade-in is declared on html.js ONLY (the inline head script sets that
   class before anything else can fail) and it is an animation with `forwards`,
   which cannot leave the page invisible even if it is interrupted. With no
   JavaScript at all the rule never matches and the page is simply there. */
@media (prefers-reduced-motion:no-preference){
  /* NO fill-mode on this animation, and that is deliberate. With `both` the
     animation's final opacity:1 keeps winning the cascade after it has finished
     (animations outrank ordinary declarations), so .leaving could never fade the
     page out and the exit half was silently dead. MEASURED: with the fill mode
     removed, body opacity is 0.42 at 150ms into a click. The animation has no
     delay, so it applies from the first frame and nothing flashes. */
  html.js body{ animation:pagein .5s var(--ease); }
  html.js.leaving body{ opacity:0; transition:opacity .26s var(--ease); }
}
@keyframes pagein{ from{ opacity:0; transform:translateY(8px); } to{ opacity:1; transform:none; } }
/* the veil sits above the fading body, so it must not fade with it */
.loader{ animation-fill-mode:forwards; }
html.js.leaving .loader{ opacity:0; }

/* --- Y11.2 the CQC certificate -------------------------------
   Adopted from the Stanley Lodge build (Jon, 6 Sep: "use the updated cqc cards
   we created ... ensure this is used going forward"). Re-skinned to the ivory
   through tokens only: the seal sits on the band tint, the rule is the paper
   hairline and the rating word is --good (re-measured for each palette; this
   build's figures are in BUILD_NOTES).

   The certificate is drawn around a published rating and nothing else. A home
   with no rating yet (a new registration) never gets one: it gets a quiet line
   in the same slot instead, and nothing is linked. */
.cqc-cert{ position:relative; max-width:820px; margin:2.4rem auto 0; background:var(--card);
  border-radius:var(--radius); box-shadow:var(--shadow-sm);
  padding:clamp(2.1rem,4.5vw,3.2rem) clamp(1.4rem,4vw,3rem); text-align:center; }
.cqc-cert::before{ content:""; position:absolute; inset:12px; pointer-events:none;
  border:1px solid var(--rule); border-radius:calc(var(--radius) - 8px); }
.cc-seal{ display:inline-grid; place-items:center; width:52px; height:52px; border-radius:50%;
  background:var(--band-tint); color:var(--primary-ink); margin-bottom:.9rem; }
.cc-seal svg{ width:26px; height:26px; }
.cc-org{ display:block; font-weight:700; font-size:.78rem; letter-spacing:.22em;
  text-transform:uppercase; color:var(--gold-ink); }
.cc-fives{ list-style:none; margin:1.9rem auto 0; padding:0; max-width:620px;
  display:grid; grid-template-columns:repeat(5,1fr); }
.cc-fives li{ position:relative; display:flex; flex-direction:column; align-items:center;
  gap:.4rem; padding:.2rem .5rem; }
.cc-fives li + li::before{ content:""; position:absolute; left:0; top:12%; bottom:12%;
  width:1px; background:linear-gradient(180deg, transparent, var(--rule) 30%, var(--rule) 70%, transparent); }
.cc-fives .tick{ width:22px; height:22px; border-radius:50%; display:grid; place-items:center;
  background:var(--good); color:#fff; }
.cc-fives .tick svg{ width:12px; height:12px; }
.cc-fives b{ font-family:var(--body); font-weight:700; font-size:.88rem; color:var(--ink); }
.cc-fives em{ font-style:normal; font-size:.78rem; color:var(--ink-soft); }
.cc-line{ margin:2rem auto 0; padding-top:1.7rem; max-width:560px; position:relative; }
.cc-line::before{ content:""; position:absolute; top:0; left:50%; transform:translateX(-50%);
  width:min(340px,80%); height:1px; background:var(--rule); }
.cc-line .big{ font-family:var(--display); font-weight:600; font-size:clamp(1.35rem,2.6vw,1.7rem);
  color:var(--ink); }
.cc-line .big .good{ color:var(--good); font-style:italic; }
.cc-line .when{ display:block; margin-top:.45rem; color:var(--ink-soft); font-size:.95rem; }
.cc-actions{ margin-top:1.9rem; display:flex; align-items:center; justify-content:center;
  gap:.55rem 1.1rem; flex-wrap:wrap; }
.cc-addr{ color:var(--ink-soft); font-size:.92rem; }
.cc-addr a{ color:var(--gold-ink); font-weight:700; text-decoration:underline; }
@media (max-width:640px){
  .cc-fives{ grid-template-columns:repeat(2, minmax(0,1fr)); gap:.9rem .4rem; max-width:340px; }
  .cc-fives li + li::before{ display:none; }
  .cc-fives li:last-child{ grid-column:1 / -1; }
}

/* --- Y11.3 the two-picture band ------------------------------
   Jon: "a dual image section to break up reviews and fees." Two photographs
   edge to edge with a line of copy between them, so the run of text blocks in
   the lower half of the home page has a breath in it. Deliberately NOT a card:
   no shadow, no radius on the outer, so it reads as a band rather than a
   third component competing with the reviews above and the fees below. */
.section.duoband{ padding:0; }
.duo{ display:grid; grid-template-columns:1fr 1fr; }
/* 16/10 rather than 4/3: at 1440 a 4/3 half-width picture is 540px tall, and two
   of them plus the line of copy made an 840px band, which stops being a breather
   between two sections and becomes a third section. */
.duo .d{ position:relative; overflow:hidden; aspect-ratio:16/10; }
.duo .d img{ width:100%; height:100%; object-fit:cover; display:block; }
.duo-say{ background:var(--accent-tint); display:grid; place-items:center;
  padding:clamp(2.6rem,5vw,4rem) var(--w1); text-align:center; }
.duo-say p{ font-family:var(--display); font-weight:500; font-size:clamp(1.3rem,2.5vw,1.85rem);
  line-height:1.45; color:var(--ink); max-width:34ch; margin:0 auto; }
.duo-say p .serif{ font-style:italic; color:var(--primary-ink); }
.duo-say .who{ display:block; margin-top:1rem; font-family:var(--body); font-size:.82rem;
  font-weight:700; letter-spacing:.18em; text-transform:uppercase; color:var(--gold-ink); }
@media (max-width:720px){ .duo{ grid-template-columns:1fr; } .duo .d{ aspect-ratio:16/10; }
  .duo .d:last-child{ display:none; } }

/* --- Y11.4 the review slider ---------------------------------
   Adopted from the dual-home engine build. One review at a time, fading, with arrows
   and dots; it advances on its own every 7 seconds and STOPS for good the
   moment anyone touches a control, so it never moves under a reader's eye.
   With no JavaScript, or if script.js fails, every review is simply stacked
   and readable rather than three quarters of the section being invisible. */
.revslider{ max-width:860px; margin:2.4rem auto 0; text-align:center; }
.rs-track{ position:relative; }
/* The hidden state is gated on html.reveal-ready, the same gate the scroll
   reveals use, and NOT on .no-js. Measured: with script.js blocked but the page
   otherwise fine (an ad blocker, a bad deploy, a slow CDN) the inline head script
   has already swapped no-js for js, so a .no-js rule never matches and five of
   the six reviews stayed invisible for good. The inline script drops
   reveal-ready after 2.5s when script.js has not booted, so this way the slider
   falls back to a plain stack in exactly the cases that matter. */
/* Jon, 7 Sep 2026: "set the length of the section so it doesn't jump up and
   down when the text is longer / shorter". Absolutely positioning the inactive
   reviews collapsed the track onto whichever one was showing, so the section
   grew and shrank by up to 126px as it advanced. Stacking all six in a single
   grid cell instead makes the track the height of the TALLEST review, always.
   It costs nothing, and unlike a measured constant it cannot go stale when the
   copy changes. */
.rs-item{ margin:0; position:relative; }
html.reveal-ready .rs-track{ display:grid; grid-template-columns:1fr; align-items:start; }
html.reveal-ready .rs-item{ grid-area:1 / 1; opacity:0; visibility:hidden;
  transition:opacity .45s var(--ease); }
html.reveal-ready .rs-item.is-on{ opacity:1; visibility:visible; }
.rs-item + .rs-item{ margin-top:2.4rem; }
html.reveal-ready .rs-item + .rs-item{ margin-top:0; }
.revslider .marks{ display:block; font-family:var(--display); font-size:3.2rem; line-height:1;
  color:var(--primary); opacity:.55; margin-bottom:.4rem; }
.revslider blockquote{ font-family:var(--display); font-weight:500;
  font-size:clamp(1.14rem,1.8vw,1.46rem); line-height:1.62; color:var(--ink);
  margin:0 auto; max-width:58ch; }
.revslider .attr{ margin-top:1.15rem; font-family:var(--body); }
.revslider .attr b{ font-weight:800; color:var(--ink); }
.revslider .attr span{ display:block; font-size:.9rem; color:var(--ink-soft); margin-top:.15rem; }
.rs-nav{ display:flex; align-items:center; justify-content:center; gap:1rem; margin-top:1.7rem; }
.rs-nav button{ width:44px; height:44px; border-radius:50%; border:1px solid var(--rule);
  background:var(--card); color:var(--primary-ink); display:grid; place-items:center; cursor:pointer;
  transition:border-color .2s var(--ease), color .2s var(--ease), background .2s var(--ease); }
.rs-nav button:hover{ border-color:var(--primary-ink); background:var(--surface); }
.rs-dots{ display:flex; gap:.5rem; }
.rs-dots button{ width:9px; height:9px; min-height:0; border-radius:50%; padding:0;
  border:0; background:var(--rule); cursor:pointer; transition:background .25s var(--ease); }
.rs-dots button[aria-selected="true"]{ background:var(--cta); }
.rs-src{ margin-top:1.2rem; font-size:.88rem; color:var(--ink-soft); }
.rs-src a{ color:var(--gold-ink); font-weight:700; text-decoration:underline; }
.no-js .rs-nav{ display:none; }
html:not(.reveal-ready) .rs-nav{ display:none; }
@media (max-width:560px){ .rs-nav button{ width:40px; height:40px; } }

/* --- Y11.6 the care accordion --------------------------------
   NOTHING HERE. Deliberately.

   An earlier pass at this section shipped an older 3/4 sticky picture, and
   another reached for Stanley Lodge's S16 (stretch the photo to the panel
   column so the two finish level). Both were wrong, and the reason is in this
   file already: the engine build went through TWO rounds with Jon on this exact
   component. Round 6 was the stretch. Round 7 REVERSED it, because stretching
   means the picture changes size every time somebody opens a panel, and Jon
   asked for "the IMAGE ITSELF to stay one size". The answer he signed off is a
   fixed-height sticky photo with the panel column capped to the same height,
   and it is already in this build at rule 14 above.

   So the component keeps its own rules and this layer adds none. The only thing
   fixed below is a mobile leak in rule 3. */

/* ============================================================
   Y12  THE REVIEWS PAGE (6 September 2026)
   Two components the single-home builds never needed, because a group
   site has to carry two scores and two voices without implying they
   are the same home.
   ============================================================ */

/* --- Y12.2 the featured review band -------------------------
   ROUND 5, Jon: the first version of this band counted five reviewers who had
   independently used the same phrase, which he read as theatrical rather than
   warm - "sounds so dramatic - change the section to just be another amazing
   review". It is now one short review, whole, set large. That works because
   the shortest review in either set happens to be the best one, so nothing is
   cropped to fit the type size. Dark band, because it should land like a held
   note between the two homes' sections rather than as another card.
   The attribution is NOT a link: it is an attribution. The profile is linked
   once, plainly, underneath. */
.echo{ background:var(--primary-deep); color:#fff; text-align:center; }
.echo .eh{ max-width:56rem; margin-inline:auto; }
.echo .lead{ font-size:.74rem; letter-spacing:.2em; text-transform:uppercase;
  font-weight:800; color:var(--accent-soft); }
.echo .said{ display:block; margin-top:1.4rem; font-family:var(--display); font-weight:500;
  font-style:italic; font-size:clamp(1.9rem,5vw,3.4rem); line-height:1.2; color:#fff; }
.echo .after{ margin-top:1.5rem; color:rgba(255,255,255,.82); font-size:1.02rem;
  max-width:46ch; margin-inline:auto; }
.echo .who{ margin-top:2rem; display:flex; flex-wrap:wrap; justify-content:center;
  gap:.5rem clamp(.8rem,2vw,1.6rem); }
.echo .who span{ font-size:.86rem; color:rgba(255,255,255,.72); display:inline-flex;
  align-items:center; gap:clamp(.8rem,2vw,1.6rem); }
.echo .who span::after{ content:""; width:4px; height:4px; border-radius:50%;
  background:var(--accent-soft); opacity:.6; }
.echo .who span:last-child::after{ display:none; }
/* On a phone the five names wrap across three lines and the separator dots end
   up dangling at the end of a line, which reads as a mistake. Below 700 the
   list becomes one name per line, which is what a list of five names wants to
   be at that width anyway. */
@media (max-width:700px){
  .echo .who{ flex-direction:column; align-items:center; gap:.55rem; }
  .echo .who span::after{ display:none; }
}
/* NAMED .note, NOT .foot. The first version of this used .foot and inherited
   `.foot a{ display:block }` from the site footer three hundred lines above,
   which put every link in this sentence on its own line and left the closing
   full stop stranded on a line of its own. Never reuse a global component's
   class name for a new element inside another component. */
.echo .note{ margin-top:1.8rem; font-size:.92rem; color:rgba(255,255,255,.7); }
.echo .note a{ color:var(--accent-soft); font-weight:700; text-decoration:underline; }

/* --- Y12.3 review page rhythm ------------------------------- */
.revhead{ display:flex; align-items:baseline; justify-content:space-between;
  gap:1rem 2rem; flex-wrap:wrap; }
.revhead .tally{ font-size:.94rem; color:var(--ink-soft); }
.revhead .tally a{ color:var(--gold-ink); font-weight:700; text-decoration:underline; }
/* the reviews grid is 2-up in the library; on a page that is nothing but
   reviews a third column at the widest sizes stops the eye from tiring */
@media (min-width:1500px){ .revpage .reviews{ grid-template-columns:repeat(3,1fr); } }
/* The library stretches every card to the height of the tallest in its row,
   which is right when the quotes are a similar length. On this page they run
   from eight words to eighty, and stretching left a third of a card empty
   under the short ones. Here each card is the height of what it holds, and
   the columns stagger, which is what a page of real reviews looks like. */
/* ROUND 5, Jon: "make the card length uniform so you don't have some long
   some short". Both grids are now six quotes of a similar length, so the
   library's stretch is right and the stagger is gone. The attribution is
   pushed to the foot of the card so any slack sits between the quote and the
   name, where it reads as breathing room rather than as a hole - the library
   already pins it with margin-top:auto, so this layer adds no rule, it only
   stops overriding one. */

/* ============================================================
   Y13  ROUND 5 (7 September 2026)
   Jon's list: section-head measure, Our Care and Reviews rhythm,
   a more present score ring, the manager block's lost paragraph
   spacing, a hero for Our Care, and the certificate extended to
   carry a mixed result honestly.
   ============================================================ */

/* --- Y13.1 the carehome.co.uk score ring --------------------
   Jon: "the rating circle is not prominent enough - make it still subtle but
   more prominent". It was a 2.2rem number floating in a flat tint disc, which
   at a glance read as a watermark rather than as the score. Three quiet moves,
   none of them loud: the number grows to fill the disc, the disc gains a
   hairline ring in the accent so it has an edge, and the fill gets a soft
   radial lift so it sits on the card rather than in it. Still no colour the
   page does not already use. */
.score .num{
  background:var(--band-tint);
  border:2px solid var(--ring);
  color:var(--cta-hover);
  font-size:3.15rem; letter-spacing:-.02em; }
.score .num{ width:118px; height:118px; }
/* the "out of 10" is the thing the number is answering, so it leads */
.score .st b{ font-size:1.14rem; }
@media (max-width:560px){
  .score .num{ width:100px; height:100px; font-size:2.5rem; }
}

/* --- Y13.2 the manager block's paragraphs -------------------
   .say is styled only inside .section-head, and the manager block on a home
   page is the one place on the site that uses it outside one. The result
   was two paragraphs with no space above or between them, jammed straight
   onto the underside of a 63px heading. Give them the same treatment they
   get everywhere else. */
.teamlead .say{ color:var(--ink-soft); font-size:1.06rem; }
.teamlead h2 + .say{ margin-top:1.3rem; }
.teamlead .say + .say{ margin-top:1.1rem; }
.teamlead .localline{ margin-top:1.7rem; }

/* --- Y13.3 the certificate, carrying a mixed result ---------
   Jon, 7 Sep 2026: the standard CQC certificate is used for a mixed result
   too. The library's rule was that a certificate is only ever
   drawn around a Good; this overturns it, and that is Jon's call to make.
   What must NOT change is the reading: the card is the same object, but it
   states what the report states. Three of the five areas are Requires
   improvement, so three of the five columns carry a hollow ring instead of a
   green tick, and the overall word is set in the same weight as a "Good"
   but in the amber token, never the green. Nobody should be
   able to glance at the two homes and come away thinking they scored alike. */
.cc-fives .mark{ width:22px; height:22px; border-radius:50%; display:grid; place-items:center;
  background:transparent; border:2px solid var(--mixed); color:var(--mixed); }
.cc-fives .mark svg{ width:11px; height:11px; }
.cc-line .big .mixed{ color:var(--mixed); font-style:italic; }
/* Requires improvement is two words where Good is one, so it wraps where Good
   does not. It takes the amber at the SAME weight the Good areas take their
   grey - the colour distinction is carried by the mark above, not by making
   the weaker areas shout. Slightly smaller so both words clear the gutters. */
.cc-fives li.is-mixed em{ color:var(--mixed); line-height:1.3; font-size:.74rem; }

/* ============================================================
   AO. ACORN & OAK CARE HOMES (24 Sep 2026)
   This client's layer. Two homes on Maidstone Road, Chatham; no client
   photography and no logo exist yet, so every image slot is a labelled
   placeholder and the brand is carried by the palette, Lora and an original
   line-drawn oak leaf and acorn. Everything here is token-driven.
   ============================================================ */

/* --- AO.0 the last literal colours, re-pointed at tokens -----------
   Early library rules still carry colours from the builds they came from
   (a green nav shadow, a cream badge, a gold selected-home glow). Every one
   is overridden here so the page genuinely comes out of tokens.css. */
.nav.scrolled, .nav.solid{ background:var(--paper-a95); box-shadow:0 10px 30px -24px rgba(var(--shadow-rgb),.45); }
.home-card .badge{ background:var(--paper-a95); }
.home-card .ph::before{ background:var(--paper-a92); }
.ph::before{ background:var(--paper-a92); }
.home-opt input:checked + label{ box-shadow:0 8px 22px -6px rgba(var(--shadow-rgb),.22); }
.home-opt input:hover + label{ border-color:var(--cta); }
.dayline .dli .dico{ box-shadow:0 10px 24px -18px rgba(var(--shadow-rgb),.5); }
.consent input{ accent-color:var(--cta); }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"]{ border-color:var(--primary-ink); }

/* --- AO.1 the mark and wordmark ------------------------------
   An oak leaf with an acorn hanging from its stem, drawn as a single weight of
   line so it re-inks with currentColor. Over the hero field it takes the
   warm on-photo copper; once the nav turns solid it takes the acorn copper.
   The wordmark is Lora with the ampersand in its italic, which is the one
   flourish the name gets. */
.brand{ gap:.62rem; }
.brand .sprig{ width:34px; flex:none; display:block; color:var(--accent-on-photo); transition:color .3s; }
.brand .sprig svg{ width:100%; height:auto; display:block; }
.nav.scrolled .brand .sprig, .nav.solid .brand .sprig{ color:var(--primary); }
.brand .wm{ display:flex; flex-direction:column; line-height:1.02; }
.brand .wm b{ font-family:var(--display); font-weight:600; font-size:1.36rem; letter-spacing:.002em; }
.brand .wm b em{ font-style:italic; font-weight:500; }
.brand .wm i{ font-style:normal; font-family:var(--body); font-weight:700; font-size:.6rem;
  letter-spacing:.22em; text-transform:uppercase; opacity:.8; margin-top:.28rem; }
@media (min-width:1041px) and (max-width:1200px){ .brand .wm b{ font-size:1.2rem; } .brand .sprig{ width:30px; } }
@media (max-width:430px){ .brand .wm b{ font-size:1.18rem; } .brand .sprig{ width:30px; } }

/* --- AO.2 first-load veil: the mark draws itself -----------------
   Once per browser session, and the library's CSS animation always clears the
   veil, so a failed script never leaves it up. Each stroke carries
   pathLength="1", so one dash value draws every line whatever its length:
   the leaf first, then its veins, then the acorn. Transform and opacity plus
   stroke-dashoffset only: nothing here relays the page. */
.loader .lmark{ gap:1.05rem; }
.loader .lsprig{ width:78px; height:auto; color:var(--accent-soft); }
.loader .lsprig path{ stroke-dasharray:1; stroke-dashoffset:1; animation:draw 1.05s var(--ease) .1s forwards; }
.loader .lsprig .v path{ animation-delay:.45s; animation-duration:.7s; }
.loader .lsprig .a path{ animation-delay:.7s; animation-duration:.8s; }
.loader .lwm{ font-family:var(--display); font-weight:600; font-size:1.02rem; letter-spacing:.16em;
  text-indent:.16em; text-transform:uppercase; color:var(--accent-soft); opacity:0;
  transform:translateY(6px); animation:aowm .9s var(--ease) .75s forwards; }
@keyframes aowm{ to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion:reduce){
  .loader .lsprig path{ animation:none; stroke-dashoffset:0; }
  .loader .lwm{ animation:none; opacity:1; transform:none; } }

/* --- AO.3 the hero's photograph slot, labelled --------------------
   Every hero sits on the brand field until the client's photographs arrive.
   The field is a designed surface, but it is still a slot waiting for a
   picture, so it says so in a small pill in the free corner, the same way
   every other placeholder on the site does. */
.hero .bg .ph-tag{ position:absolute; right:var(--w1); bottom:1.3rem; z-index:3;
  background:var(--paper-a92); color:var(--primary-ink); font-size:.72rem; font-weight:700;
  letter-spacing:.01em; line-height:1.4; padding:.36rem .9rem; border-radius:999px;
  max-width:min(30rem,calc(100% - 2 * var(--w1))); }
@media (max-width:900px){
  .hero .bg .ph-tag{ right:auto; left:var(--w1); bottom:.9rem; }
  .hero.left .inner{ padding-bottom:4.4rem; }
}
.hero .gold-rule, .hero.left .gold-rule{ background:var(--accent-on-photo); }

/* --- AO.4 marks for facts still to come -----------------------------
   .todo is the library's visibly unreal mark: a tinted pill with the words in
   square brackets. Nothing on this site that is not yet known looks real. */
.todo{ font-family:var(--body); letter-spacing:0; text-transform:none; }
.hero .todo{ font-size:.92em; }
.kchip.todo-chip{ background:var(--card); border:1px dashed var(--primary); color:var(--primary-ink); }
.foot .todo{ display:inline-block; margin-bottom:.3rem; }
.foot .fserv .todo{ font-size:.92em; }
.mobile-menu .mm-tel.is-todo{ display:block; padding:.95rem .2rem; border-bottom:1px solid var(--rule);
  color:var(--ink-soft); font-family:var(--display); font-size:1.2rem; }

/* --- AO.5 footer: one phone per home column ------------------------
   The library's footer expects a phone AND an email per home and dims the
   last link in a column. Each column here has one number, which is the most
   useful thing in it, so it stays at full weight. */
.foot a.fkey:last-of-type{ font-weight:600; color:#fff; font-size:.98rem; }

/* --- AO.6 fees: Acorn House's published ranges ----------------------
   The numbers' one seat on the home page. A plain table on a card, beside the
   words that explain what the figure depends on; Oak House sits beneath it on
   one quiet line. */
.feesrow .fr-fees{ align-self:center; }
.fr-fees h3{ font-size:1.32rem; }
.fr-fees .feewrap{ margin-top:1rem; }
.fr-fees .feetable th, .fr-fees .feetable td{ white-space:nowrap; }
.fr-fees .feetable thead th{ color:var(--primary-ink); background:var(--surface); font-size:.74rem; letter-spacing:.1em; }
.fr-fees .feetable tbody th{ text-transform:none; letter-spacing:0; font-size:1rem; font-weight:700; }
.fr-fees .feetable td{ color:var(--ink); font-weight:600; }
.fr-fees .feenote{ margin-top:.9rem; font-size:.92rem; color:var(--ink-soft); max-width:52ch; }
.fr-fees .oakfee{ margin-top:1.3rem; display:flex; gap:.7rem; align-items:baseline; flex-wrap:wrap;
  background:var(--card); border-radius:var(--radius-sm); padding:1rem 1.2rem; box-shadow:var(--shadow-sm); }
.fr-fees .oakfee b{ font-family:var(--display); font-weight:600; font-size:1.08rem; color:var(--ink); }
.fr-fees .oakfee span{ color:var(--ink-soft); font-size:.98rem; }
.fr-fees .oakfee a{ color:var(--primary-ink); font-weight:700; text-decoration:underline; }
@media (max-width:1000px){ .feesrow .fr-fees{ order:0; } }

/* --- AO.7 a home that has no rating yet -----------------------------
   Oak House sits in the certificate's slot with one quiet, factual line.
   No certificate (it is drawn around a rating, and there is none), no seal
   pretending to be one, nothing linked. */
.cqc-quiet{ max-width:44rem; margin-inline:auto; text-align:center; }
.cqc-quiet .cc-seal{ margin-bottom:.8rem; }
.cqc-quiet p{ color:var(--ink); font-size:1.12rem; line-height:1.6; }
.cqc-quiet .todo{ display:inline-block; margin-top:.35rem; }

/* --- AO.8 home-card placeholder label below 1000px -------------------
   Below 1000 the card is a picture with its caption underneath, so the
   picture's bottom edge is free again and the label goes back to the
   library's strip rather than disappearing. Every slot stays labelled. */
@media (max-width:1000px){
  .home-card .ph::before{ left:0; right:0; top:auto; bottom:0; width:auto; max-width:none;
    height:2.2rem; line-height:2.2rem; padding:0 1rem; border-radius:0; text-align:center;
    white-space:nowrap; font-size:.72rem; }
}

/* --- AO.9 small things ---------------------------------------------- */
.review .src{ margin-top:.85rem; }
.review .src a, .score .st a{ color:var(--primary-ink); font-weight:700; text-decoration:underline; }
.hl-list .hl .hl-body .eyebrow{ display:block; margin-bottom:.4rem; }
.loc-details .li .todo{ display:inline-block; }
.aside-note .todo, .form-error .todo, .enq-success .todo{ display:inline-block; }
.contact-aside .crow .todo{ display:inline-block; }
.hero-tel .sep{ opacity:.6; padding-inline:.35rem; }
/* The care accordion's frame height. script.js measures the real figure at
   runtime and writes it onto the section, so this is only the first-paint
   value; it is set for THIS build's four panels, not the six it was cloned
   with, so the first paint matches the measured one (see BUILD_NOTES). */
:root{ --ca-frame:540px; }
/* The CQC "Good" in the inspection heading takes the rating green, not the
   copper every other italic word takes. Found by looking: Y1's italic-word
   colour (0,2,1) outranked R3.1's .good (0,2,0), so the word rendered copper. */
.section-head h2 .serif.good{ color:var(--good); }
/* The footer column is a flex column, so a placeholder pill stretched to the
   full column width. It sits at its own width like the phone link beside it. */
.foot .fcol > .todo{ align-self:flex-start; }
.ctatels .sep{ opacity:.6; padding-inline:.4rem; }
/* Focus rings on dark grounds. Measured: tabbing to the brand link over the hero
   field drew the copper ring (#7C4D26) on russet, about 2:1, because the
   library only whitened the ring for .navlinks and .nav-tel. Every focusable
   thing in the transparent bar, the footer, the featured-review band and the
   cookie notice now takes a light ring. PROMOTE UPSTREAM. */
.nav:not(.scrolled):not(.solid) a:focus-visible,
.nav:not(.scrolled):not(.solid) button:focus-visible{ outline-color:#fff; }
.foot a:focus-visible, .echo a:focus-visible,
.cookie a:focus-visible, .cookie button:focus-visible{ outline-color:var(--accent-soft); }
/* --- AO.10 the nav bar never wraps -----------------------------------
   Measured in the 1536 to 340 sweep: between 1041 and 1240 the library's 6.2
   rule (gap 1.5rem, later in the file than the R6.8 steps) widened the link
   row enough that "Arrange a visit" broke onto two lines inside its pill (98px
   tall at 1216) and the wordmark's second line wrapped too, so the bar jumped
   from 97 to 139px at a few widths. Nothing in the bar may wrap; the link gap
   gives way instead. PROMOTE UPSTREAM. */
.nav-actions .btn, .brand .wm b, .brand .wm i{ white-space:nowrap; }
@media (min-width:1041px) and (max-width:1240px){ .navlinks{ gap:1.05rem; } }
/* --- AO.11 focus rings that were clipped or too faint --------------------
   Measured by tabbing every page and diffing the pixels around each stop:
   - the consent checkbox showed only the form's soft halo (--focus-ring at
     42% alpha), 1.96:1 against the card;
   - a home card's .cardlink is inset:0 inside a card with overflow:hidden, so
     its outline was clipped away; on desktop the hover scrim changed, on a
     phone (no hover styles) nothing visible happened at all;
   - the map iframe sits in a rounded, clipped frame: no ring at all.
   The ring now goes on the container, outside the clip. PROMOTE UPSTREAM. */
.consent input:focus-visible{ outline:2px solid var(--cta); outline-offset:3px; border-radius:4px; }
.home-card:has(.cardlink:focus-visible){ outline:3px solid var(--primary-ink); outline-offset:4px; }
.loc-map:focus-within{ outline:3px solid var(--primary-ink); outline-offset:4px; }
/* --- AO.12 nothing under 12px, and every placeholder reads in full --------
   Font-size audit (every visible text node, 390 and 1536): the wordmark's
   second line was 10.8px, the photo label on a home card 11.2px and the
   contact page's place labels 11.9px, all under the craft floor's 12px. And
   at 390 the photo-slot strips cut their own labels off with an ellipsis
   ("residents and staff..."), which defeats a label whose whole job is to
   say which photograph goes where: the strip now grows to fit. */
.brand .wm i{ font-size:max(12px,.67rem); letter-spacing:.16em; }
.home-card .ph::before{ font-size:max(12px,.67rem); }
.contact-grid .place{ font-size:max(12px,.67rem); }
.ph::before{ height:auto; min-height:2.2rem; line-height:1.35; padding:.5rem 1rem;
  white-space:normal; text-overflow:clip; display:flex; align-items:center; justify-content:center; }
@media (max-width:1000px){
  .home-card .ph::before{ height:auto; line-height:1.35; padding:.5rem 1rem; white-space:normal; }
}
/* text-wrap:balance on a short paragraph at phone width evens the lines by
   making them all short: measured 245px of a 308px column. Balance is for
   headings; below 700 the paragraph fills its measure. */
@media (max-width:700px){ .section-head .say, .hero .sub{ text-wrap:wrap; } }

/* ============================================================
   AO ROUND 2 (30 Sep 2026)
   Jon: "a good start but a bit basic". The client sent four real exteriors,
   and the remaining image slots are dressed from the shared library as a
   flagged golden-rule-5 deviation (every stand-in lives in
   assets/photos/lib/ and nowhere else). Five components are ported from the
   N-series reference build and re-inked with this build's tokens: the
   same/change panel, the numbered stay steps, the four funding doors, the
   read-next strip and the meals beat's review note. Components only: no
   copy, facts, faces or colours came across with them.
   ============================================================ */

/* --- AO.13 photo heroes -------------------------------------------
   The client's exteriors are sunny, and the brightest thing in every one of
   them is the sky, which is exactly where a left-aligned headline sits. So a
   photo hero gets its own wash: heaviest at the text edge, easing off
   towards the house, plus the top band the nav needs. Measured, not judged:
   see BUILD_NOTES round 2 for the worst-pixel figures behind every line of
   hero text. Below 900px the text spans the whole picture, so the wash is
   even across it. */
.hero.photo .bg > img.cover{ filter:saturate(.96) brightness(.84); }
.hero.photo .bg::after{
  background:
    linear-gradient(180deg, rgba(var(--shadow-rgb),.55) 0%, rgba(var(--shadow-rgb),0) 22%),
    linear-gradient(90deg, rgba(var(--shadow-rgb),.86) 0%, rgba(var(--shadow-rgb),.78) 38%, rgba(var(--shadow-rgb),.46) 66%, rgba(var(--shadow-rgb),.30) 100%),
    linear-gradient(0deg, rgba(var(--shadow-rgb),.55) 0%, rgba(var(--shadow-rgb),0) 30%); }
@media (max-width:900px){
  .hero.photo .bg::after{ background:
    linear-gradient(180deg, rgba(var(--shadow-rgb),.74) 0%, rgba(var(--shadow-rgb),.72) 55%, rgba(var(--shadow-rgb),.86) 100%); }
}
/* Two homes, one road: the home page (fronts) and the contact page (sides)
   show both houses side by side, split by a hairline of paper. Below 900 the
   second picture is dropped rather than squeezed into a sliver; it is
   lazy, so a phone never downloads it. */
.hero .bg.split{ display:grid; grid-template-columns:1fr 1fr; }
.hero .bg.split > img.cover{ position:relative; inset:auto; width:100%; height:100%; min-width:0; }
.hero .bg.split::before{ content:""; position:absolute; top:0; bottom:0; left:50%; width:2px;
  margin-left:-1px; background:var(--paper-a92); opacity:.55; z-index:1; }
@media (max-width:900px){
  .hero .bg.split{ grid-template-columns:1fr; }
  .hero .bg.split > img.cover + img.cover, .hero .bg.split::before{ display:none; }
}
/* The small true caption for a real photo hero, in the slot the
   "photograph to come" pill used: which house, which number. */
.hero .bg .ph-cap{ position:absolute; right:var(--w1); bottom:1.3rem; z-index:3;
  color:#fff; font-size:.8rem; font-weight:700; letter-spacing:.02em;
  background:rgba(var(--shadow-rgb),.62); padding:.3rem .8rem; border-radius:999px; }
@media (max-width:900px){ .hero .bg .ph-cap{ display:none; } }

/* --- AO.14 real photographs in the library's slots ---------------------
   Every slot was built around a nested .ph; a real <img class="cover"> takes
   the same absolute fill so nothing changes size when a placeholder is
   swapped for a picture. */
.framed > img.cover, .fd-photo > img.cover, .hl-img > img.cover, .home-img > img.cover,
.ca-img > img.cover, .tl-photo > img.cover{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.home-card .home-img > img.cover{ transition:transform .9s var(--ease); }
/* The card's reading scrim still carried a literal green from the build it
   was cloned from. Over a real photograph that tint shows, so it is re-inked
   onto the shadow token like everything else. */
.home-card .scrim{ background:linear-gradient(180deg, rgba(var(--shadow-rgb),0) 34%, rgba(var(--shadow-rgb),.84) 100%); }
.home-card:hover .scrim{ background:linear-gradient(180deg, rgba(var(--shadow-rgb),.2) 0%, rgba(var(--shadow-rgb),.9) 100%); }
/* A review note inside a copy column sits on the band tint; on a tinted
   band it would vanish, so there it becomes a card. */
.band-tint .qnote, .band-accent .qnote{ background:var(--card); box-shadow:var(--shadow-sm); }

/* --- AO.15 the reassurance row ------------------------------------------
   The library's .rowband (white, ruled top and bottom) carrying an icon row
   of four. It sits directly under a surface section, so the white and the
   rules are what separate it; the row itself is unboxed. */
.rowband .icon-row.four .ir h3{ min-height:0; }
@media (min-width:1025px){ .rowband .icon-row.four .ir h3{ min-height:1.4em; } }

/* --- AO.16 same / adapts (ported: the "familiar things" panel) -----------
   One white sheet split by a faded hairline, so it reads as one thought, not
   a comparison table. What stays takes the acorn copper (open rings); what
   gently adapts takes the oak green (small chevrons). Ink on white inside. */
.sx-sq{ margin-top:2.4rem; display:grid; background:var(--card); border-radius:var(--radius);
  box-shadow:var(--shadow-sm); overflow:hidden; }
.sx-sq-col{ position:relative; padding:clamp(1.5rem,4.4vw,2.5rem); }
.sx-sq-col + .sx-sq-col{ border-top:1px solid var(--rule); }
.sx-sq-lab{ display:block; font-size:.74rem; letter-spacing:.2em; text-transform:uppercase; font-weight:800; }
.sx-sq-same .sx-sq-lab{ color:var(--primary-ink); }
.sx-sq-change .sx-sq-lab{ color:var(--cta-hover); }
.sx-sq-col h3{ font-family:var(--display); font-weight:600; font-size:clamp(1.3rem,2.6vw,1.62rem);
  margin-top:.5rem; line-height:1.16; }
.sx-sq-list{ list-style:none; margin:1.3rem 0 0; padding:0; display:flex; flex-direction:column; gap:1rem; }
.sx-sq-list li{ position:relative; padding-left:1.85rem; color:var(--ink-soft); font-size:1rem; }
.sx-sq-list li b{ font-family:var(--body); font-weight:800; color:var(--ink); }
.sx-sq-same .sx-sq-list li::before{ content:""; position:absolute; box-sizing:border-box;
  left:0; top:.42em; width:12px; height:12px; border-radius:50%; border:2px solid var(--primary); }
.sx-sq-change .sx-sq-list li::before{ content:""; position:absolute; box-sizing:border-box;
  left:1px; top:.5em; width:9px; height:9px; transform:rotate(-45deg);
  border-right:2px solid var(--cta); border-bottom:2px solid var(--cta); }
.sx-sq-foot{ margin:1.8rem auto 0; max-width:62ch; text-align:center; color:var(--ink-soft); font-size:1rem; }
.sx-sq-foot a{ color:var(--primary-ink); font-weight:700; text-decoration:underline; }
@media (min-width:800px){
  .sx-sq{ grid-template-columns:1fr 1fr; }
  .sx-sq-col + .sx-sq-col{ border-top:0; }
  .sx-sq-col + .sx-sq-col::before{ content:""; position:absolute; left:0; top:2.2rem; bottom:2.2rem;
    width:1px; background:linear-gradient(180deg, transparent, var(--rule) 15%, var(--rule) 85%, transparent); }
}

/* --- AO.17 numbered steps (ported: "how a stay comes together") ---------
   Used for "how moving in works" on the home page and Oak House. Four tiles,
   a ghost numeral in the corner (decorative: the order is in the markup and
   in each heading), a short oak-green tick, and a copper chevron in the gap
   pointing down the stack on a phone and along the row on a wide screen.
   Boxed and numbered, so it cannot be confused with the contact page's
   unboxed steps. */
.sx-stay{ --sx-sgap:1.15rem; margin-top:2.6rem; display:grid; gap:var(--sx-sgap); counter-reset:none; }
.sx-step{ position:relative; background:var(--card); border-radius:var(--radius-sm); box-shadow:var(--shadow-sm);
  padding:1.5rem 1.5rem 1.6rem; }
.sx-step .sx-n{ position:absolute; right:1rem; top:.5rem; font-family:var(--display);
  font-weight:600; font-size:3.4rem; line-height:1; color:var(--primary); opacity:.22; pointer-events:none; }
.sx-step .sx-tick{ display:block; width:26px; height:2px; border-radius:2px; background:var(--cta); margin-bottom:.9rem; }
.sx-step h3{ position:relative; font-family:var(--body); font-weight:800; font-size:1.06rem;
  letter-spacing:.01em; padding-right:2.5rem; }
.sx-step p{ position:relative; margin-top:.5rem; color:var(--ink-soft); font-size:1rem; }
.sx-step + .sx-step::before{ content:""; position:absolute; left:50%; margin-left:-5px;
  top:calc(var(--sx-sgap) / -2 - 6px); width:9px; height:9px; transform:rotate(45deg);
  border-right:2px solid var(--primary); border-bottom:2px solid var(--primary); }
.sx-stay-foot{ margin-top:1.8rem; text-align:center; }
@media (min-width:561px){
  .sx-stay{ grid-template-columns:1fr 1fr; column-gap:1.2rem; }
  .sx-step + .sx-step::before{ display:none; }
}
@media (min-width:960px){
  .sx-stay{ --sx-sgap:clamp(1rem,1.9vw,1.5rem); grid-template-columns:repeat(4,1fr);
    column-gap:var(--sx-sgap); align-items:stretch; }
  .sx-step + .sx-step::before{ display:block; left:calc(var(--sx-sgap) / -2 - 4px);
    margin-left:0; top:2.5rem; transform:rotate(-45deg); }
}

/* --- AO.18 the four funding doors (ported) --------------------------------
   Four arched cards drawn like doors: a deep radius across the top, a copper
   arch set inside the edge, a small label, and a "may apply when" line pinned
   to the foot of every card so the four hairlines sit level. General routes
   only: which of them each home accepts is a gap for Jon, not a claim. */
.sx-fourdoors{ margin-top:2.6rem; display:grid; grid-template-columns:1fr; gap:1.5rem; }
.sx-door{ position:relative; display:flex; flex-direction:column; background:var(--card);
  border-radius:150px 150px var(--radius) var(--radius); padding:3.1rem 1.9rem 2rem; box-shadow:var(--shadow-sm); }
.sx-door::before{ content:""; position:absolute; left:20px; right:20px; top:18px; bottom:18px;
  border:1px solid var(--primary); opacity:.38; pointer-events:none; border-radius:130px 130px 12px 12px; }
.sx-door > *{ position:relative; z-index:1; }
.sx-door .sx-door-lab{ display:block; text-align:center; font-family:var(--body); font-size:.74rem;
  letter-spacing:.2em; text-transform:uppercase; font-weight:800; color:var(--primary-ink); }
.sx-door h3{ margin-top:.55rem; text-align:center; font-size:1.24rem; line-height:1.16; }
.sx-door p{ margin-top:1rem; color:var(--ink-soft); font-size:1rem; }
.sx-door p:last-of-type{ margin-bottom:1.5rem; }
.sx-door .sx-door-fit{ margin-top:auto; padding-top:1.15rem; border-top:1px solid var(--rule);
  font-size:.94rem; font-weight:600; color:var(--ink); }
.sx-door .sx-door-fit b{ font-family:var(--body); font-weight:800; color:var(--primary-ink); }
@media (min-width:561px){
  .sx-fourdoors{ grid-template-columns:1fr 1fr; gap:clamp(1.5rem,2.6vw,2.2rem); }
  .sx-door{ padding:3.3rem 2.1rem 2.1rem; }
}
.sx-fourdoors{ max-width:1080px; margin-inline:auto; }
.sx-doors-foot{ margin:2rem auto 0; max-width:64ch; text-align:center; color:var(--ink-soft); }
.sx-doors-foot a{ color:var(--primary-ink); font-weight:700; text-decoration:underline; }

/* --- AO.19 read next (ported) -----------------------------------------
   Small photo-side link cards at the foot of an inner page. Thumbnails are
   decorative (alt=""), the words carry the link. */
.sx-readnext{ margin-top:1.1rem; display:grid; gap:1rem; }
.sx-rn{ display:grid; grid-template-columns:84px 1fr auto; gap:1rem; align-items:center;
  background:var(--card); border-radius:var(--radius-sm); box-shadow:var(--shadow-sm);
  padding:.65rem 1rem .65rem .65rem; color:var(--ink); outline-offset:4px;
  transition:transform .25s var(--ease), box-shadow .25s var(--ease); }
.sx-rn:hover{ transform:translateY(-2px); box-shadow:0 24px 42px -30px rgba(var(--shadow-rgb),.6); }
.sx-rn:focus-visible{ outline:3px solid var(--primary-ink); }
.sx-rn-img{ position:relative; border-radius:11px; overflow:hidden; aspect-ratio:1/1; background:var(--band-tint); }
.sx-rn-img img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.sx-rn-k{ display:block; font-size:.74rem; letter-spacing:.16em; text-transform:uppercase; font-weight:800; color:var(--primary-ink); }
.sx-rn-h{ display:block; margin-top:.25rem; font-family:var(--display); font-weight:600; font-size:1.08rem; line-height:1.25; color:var(--ink); }
.sx-rn-go{ flex:none; color:var(--primary-ink); }
.sx-rn-go svg{ display:block; width:18px; height:18px; }
@media (min-width:700px){
  .sx-readnext{ grid-template-columns:repeat(3,1fr); gap:1.2rem; }
  .sx-rn{ grid-template-columns:76px 1fr; padding:.7rem .9rem .8rem .7rem; }
  .sx-rn-go{ display:none; }
}
@media (prefers-reduced-motion:reduce){ .sx-rn{ transition:none; } .sx-rn:hover{ transform:none; } }

/* --- AO.20 a short walk along the road (Oak House) -----------------------
   The two numbers on one line: a copper hairline between two stops, then a
   card that is the way through to Acorn House's page, carrying Acorn's own
   front (never Oak's). */
.walk{ display:grid; grid-template-columns:1.05fr .95fr; gap:clamp(2rem,5vw,4.5rem); align-items:center; }
.route{ margin-top:1.8rem; display:grid; grid-template-columns:auto 1fr auto; align-items:center; gap:.9rem;
  max-width:30rem; }
.route .stop{ display:flex; flex-direction:column; gap:.1rem; }
.route .stop b{ font-family:var(--display); font-weight:600; font-size:1.08rem; color:var(--ink); }
.route .stop span{ font-size:.9rem; color:var(--ink-soft); }
.route .stop.r{ text-align:right; }
.route .line{ position:relative; height:2px; background:var(--primary); opacity:.5; }
.route .line::before, .route .line::after{ content:""; position:absolute; top:50%; width:12px; height:12px;
  margin-top:-6px; border-radius:50%; background:var(--surface); border:2px solid var(--primary); }
.route .line::before{ left:-2px; } .route .line::after{ right:-2px; background:var(--primary); }
.walkcard{ display:block; background:var(--card); border-radius:var(--radius); overflow:hidden;
  box-shadow:var(--shadow); color:var(--ink); transition:transform .3s var(--ease); outline-offset:5px; }
.walkcard:hover{ transform:translateY(-3px); }
.walkcard:focus-visible{ outline:3px solid var(--primary-ink); }
.walkcard .wc-img{ position:relative; aspect-ratio:16/10; }
.walkcard .wc-img img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.walkcard .wc-body{ padding:1.3rem 1.5rem 1.5rem; }
.walkcard .wc-body .k{ display:block; font-size:.74rem; letter-spacing:.16em; text-transform:uppercase; font-weight:800; color:var(--primary-ink); }
.walkcard .wc-body b{ display:block; margin-top:.3rem; font-family:var(--display); font-weight:600; font-size:1.4rem; }
.walkcard .wc-body span.go{ display:inline-block; margin-top:.5rem; font-weight:800; color:var(--primary-ink); text-decoration:underline; }
@media (max-width:900px){ .walk{ grid-template-columns:1fr; } }
@media (prefers-reduced-motion:reduce){ .walkcard{ transition:none; } .walkcard:hover{ transform:none; } }

/* --- AO.21 two maps, side by side (contact) ----------------------------- */
.maps2{ margin-top:2.2rem; display:grid; grid-template-columns:1fr 1fr; gap:clamp(1.4rem,3vw,2.4rem); }
.maps2 .m h3{ font-size:1.4rem; }
.maps2 .m .addr{ margin-top:.3rem; color:var(--ink-soft); font-size:1rem; }
.maps2 .loc-map{ margin-top:1rem; box-shadow:var(--shadow-sm); }
.maps2 .loc-map iframe{ min-height:340px; }
.maps2 .m .go{ display:inline-block; margin-top:.9rem; font-weight:800; color:var(--primary-ink); text-decoration:underline; }
@media (max-width:860px){ .maps2{ grid-template-columns:1fr; } .maps2 .loc-map iframe{ min-height:300px; } }

/* --- AO.22 three doors on the russet band (contact) --------------------
   The library's doors take white text on --primary-deep; the value line is
   a link or a to-confirm mark, never a fake address. */
.band-deep .door .todo{ background:var(--accent-soft); color:var(--primary-deep); }
.band-deep .door a.val{ text-decoration:underline; text-underline-offset:4px; text-decoration-thickness:1px; }
.band-deep .door a:focus-visible{ outline-color:var(--accent-soft); }
.door .val + .val{ margin-top:.25rem; }
.door .vals{ display:flex; flex-direction:column; align-items:center; }
.door .vals small{ display:block; margin-top:.6rem; font-size:.78rem; letter-spacing:.14em; text-transform:uppercase;
  font-weight:800; color:var(--accent-soft); }
.hero .bg .ph-cap.l{ right:calc(50% + 1.2rem); }
.hero .bg.split .ph-cap:not(.l){ right:1.2rem; }
/* Measured at 1536: the headline ran 17px past the seam into the second
   house. The text half is widened to 60% and the text column capped to end
   2.5rem short of the seam, wherever the hold places its left edge. */
@media (min-width:901px){
  .hero .bg.split{ grid-template-columns:1.5fr 1fr; }
  .hero .bg.split::before{ left:60%; }
  .hero .bg .ph-cap.l{ right:calc(40% + 1.2rem); }
  .hero.twin .inner{ max-width:calc(60vw - max(var(--w1), (100vw - var(--hold)) / 2 + var(--w1)) - 2.5rem); }
}
.hero .bg img.op-r{ object-position:74% 50%; }
.hero .bg img.op-l{ object-position:30% 50%; }
.hero .todo, .hero-tel .todo{ white-space:nowrap; }
.hl-img > img.op-t, .if-img img.op-t{ object-position:50% 28%; }
.loc-details .li a{ font-weight:700; text-decoration:underline; text-underline-offset:3px; }
.feesrow .fr-list a{ color:var(--primary-ink); font-weight:700; text-decoration:underline; text-underline-offset:3px; }
.walkcard .wc-img, .walkcard .wc-body{ display:block; }
/* Measured on the reviews page at 1536: the card sat over the two people in
   the photograph. This variant puts the card on the right and mirrors the
   wash, so the faces stay in view. */
.quote-photo.qp-right .qp-card{ margin-left:auto; }
.quote-photo.qp-right .qp-bg::after{ background:linear-gradient(270deg, rgba(var(--shadow-rgb),.72) 0%, rgba(var(--shadow-rgb),.34) 62%, rgba(var(--shadow-rgb),.5) 100%); }
.quote-photo.qp-right .qp-bg img.cover{ object-position:30% 50%; }
.band-deep h2 .serif{ color:var(--accent-soft); }
.route .line{ min-width:56px; }
/* Measured: "Reviews" in the nav sat exactly on the paper seam of the split
   hero, 2.33:1 at its worst pixel. The seam now starts below the nav bar. */
.hero .bg.split::before{ background:linear-gradient(180deg, transparent 0, transparent 124px, var(--paper-a92) 160px); }
/* Measured over the real fronts (card labels, worst pixel): at rest the Oak
   card's place label was 3.31:1 over its white render; on hover, when the
   label climbs to show the description, the place label fell to 2.17 and the
   name to 3.85. The wash is now deep wherever the label can sit, and lighter
   above it so the house still shows. Below 1000px the label sits under the
   picture on the russet ground, so none of this applies there. */
@media (min-width:1001px){
  .home-card .scrim{ background:linear-gradient(180deg, rgba(var(--shadow-rgb),0) 28%, rgba(var(--shadow-rgb),.6) 52%, rgba(var(--shadow-rgb),.9) 72%, rgba(var(--shadow-rgb),.93) 100%); }
  .home-card:hover .scrim, .home-card:has(.cardlink:focus-visible) .scrim{ background:linear-gradient(180deg, rgba(var(--shadow-rgb),.55) 0%, rgba(var(--shadow-rgb),.9) 30%, rgba(var(--shadow-rgb),.93) 100%); }
}
/* --- AO.23 focus, measured on every tab stop ----------------------------
   - Form fields showed only the soft halo when focused: 1.96:1 against the
     card. They now take a solid oak-green ring as well (6.5:1 on the card).
   - A link inside a CLOSED accordion panel ("explained above", added to the
     Our Care FAQ this round) still took keyboard focus while clipped to zero
     height, so focus vanished. Closed panels are now hidden from the tab order
     once the script has booted; the visibility change waits for the closing
     slide to finish. With no script, or a failed one, the reveal gate drops
     and every panel stays open and reachable, exactly as before. PROMOTE. */
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible{
  outline:2px solid var(--cta); outline-offset:2px; }
html.reveal-ready .acc-item:not(.open) > .acc-body{ visibility:hidden;
  transition:max-height .4s var(--ease), visibility 0s linear .4s; }
html.reveal-ready .acc-item.open > .acc-body{ visibility:visible; transition:max-height .4s var(--ease), visibility 0s; }

/* ============================================================
   AO R3.1 .sx-pack - "What to bring" (Our Care, above Paying for care)
   The library packing case, consolidated: one white case on the band, a copper handle on the top edge,
   ONE centred label, eight items in a single grid that fills column-major so
   the two aisles stay level row by row, a hairline foot. Icons share one
   1.6px non-scaling stroke. Contrast: ink 15.87 / ink-soft 7.6ish on white;
   copper label #7C4D26 on white 7.13.
   ============================================================ */
.sx-pack{ position:relative; margin-top:3.4rem; background:var(--card);
  border:1px solid var(--rule); border-radius:var(--radius); box-shadow:var(--shadow-sm);
  padding:2.1rem 1.35rem 1.9rem; }
.sx-pack::before{ content:""; position:absolute; left:50%; top:-26px; width:84px; height:26px;
  transform:translateX(-50%); border:1.5px solid var(--accent-line); border-bottom:0;
  border-radius:42px 42px 0 0; opacity:.9; pointer-events:none; }
.sx-pack-one{ display:block; text-align:center; font-family:var(--body); font-weight:800;
  font-size:.75rem; letter-spacing:.2em; text-transform:uppercase; color:var(--gold-ink);
  margin-bottom:1.6rem; }
.sx-pack-cols{ position:relative; display:grid; row-gap:1.5rem; }
.sx-pack-item{ display:grid; grid-template-columns:46px 1fr; gap:1rem; align-items:start; }
.sx-pack-ico{ width:46px; height:46px; color:var(--primary-ink); display:grid; place-items:center; }
.sx-pack-ico svg{ display:block; width:100%; height:100%; stroke-width:1.6; }
.sx-pack-ico svg *{ vector-effect:non-scaling-stroke; }
.sx-pack-item h3{ font-family:var(--body); font-weight:800; font-size:1rem; letter-spacing:.01em;
  line-height:1.3; margin-top:.2rem; color:var(--ink); }
.sx-pack-item p{ margin-top:.25rem; color:var(--ink-soft); font-size:.96rem; }
.sx-pack-foot{ margin-top:1.9rem; padding-top:1.3rem; border-top:1px solid var(--rule);
  color:var(--ink-soft); font-size:.98rem; }
.sx-pack-foot b{ font-family:var(--body); font-weight:800; color:var(--ink); }
@media (min-width:561px){
  .sx-pack{ padding:2.5rem 2.2rem 2.2rem; }
  .sx-pack-foot{ display:flex; gap:1rem; align-items:flex-start; }
  .sx-pack-foot b{ flex:none; }
}
@media (min-width:860px){
  .sx-pack{ padding:2.9rem 2.9rem 2.5rem; }
  .sx-pack-item{ grid-template-columns:52px 1fr; gap:1.15rem; }
  .sx-pack-ico{ width:52px; height:52px; }
}
@media (min-width:901px){
  .sx-pack-cols{ grid-template-columns:1fr 1fr; grid-template-rows:repeat(4, 1fr);
    grid-auto-flow:column; column-gap:clamp(2.6rem,5vw,4.4rem); row-gap:1.6rem; }
  .sx-pack-cols::before{ content:""; position:absolute; left:50%; top:4%; bottom:4%; width:1px;
    background:linear-gradient(180deg, transparent 0%, rgba(var(--shadow-rgb),.16) 22%,
      rgba(var(--shadow-rgb),.16) 78%, transparent 100%); }
}

/* ============================================================
   AO R3.2 the score cards (library paired score + score ring,
   Jon 30 Sep 2026). Acorn House only for now: .solo centres the one card
   at the width it would have as half of a pair, so adding Oak House later
   is a paste plus removing "solo", with nothing else to re-measure.
   ============================================================ */
.scorepair{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(1rem,2.4vw,1.8rem);
  margin-top:2.4rem; }
.scorepair.solo{ grid-template-columns:minmax(0,30rem); justify-content:center; }
.sp{ background:var(--card); border-radius:var(--radius); box-shadow:var(--shadow-sm);
  padding:clamp(1.6rem,3vw,2.4rem); text-align:center; }
.sp .num{ width:114px; height:114px; margin:0 auto; border-radius:50%;
  background:var(--band-tint); border:2px solid rgba(138,91,51,.42);
  display:grid; place-items:center; font-family:var(--display); font-weight:600;
  font-size:3.15rem; letter-spacing:-.02em; color:var(--primary-ink); line-height:1; }
.sp h3{ margin-top:1.1rem; font-family:var(--display); font-weight:600;
  font-size:clamp(1.3rem,2.2vw,1.6rem); color:var(--ink); }
.sp .place{ display:block; margin-top:.25rem; font-size:.75rem; letter-spacing:.18em;
  text-transform:uppercase; font-weight:800; color:var(--gold-ink); }
.sp p{ margin-top:.9rem; color:var(--ink-soft); font-size:.96rem; }
.sp .prof{ display:inline-block; margin-top:1rem; font-weight:700; color:var(--gold-ink);
  text-decoration:underline; font-size:.94rem; }
@media (max-width:760px){ .scorepair{ grid-template-columns:1fr; } }
@media (max-width:560px){ .sp .num{ width:100px; height:100px; font-size:2.5rem; } }
/* AO R3.3 the earlier-reviews block carries two cards, not six: centre the pair
   under a centred head so the row does not sit lopsided in a three-column grid. */
@media (min-width:861px){
  .revpair .reviews{ grid-template-columns:repeat(2,minmax(0,1fr)); max-width:54rem; margin-inline:auto; }
}
@media (min-width:1500px){ .revpage.revpair .reviews{ grid-template-columns:repeat(2,minmax(0,1fr)); } }

/* ============================================================
   AO R3.4 the two-house hero, text across both pictures
   Jon, 2 Oct 2026: on the home and contact heroes the copy was squeezed into
   the left (Acorn) picture and "looks silly"; it should run across both.
   From 901px the split goes back to an even 50 / 50, the copy is centred
   over the seam on one message for both homes, and the wash is even across
   both pictures with a soft darker pool behind the words (the Oak front is a
   white render in full sun, so it needs as much help as the brick). The paper
   seam is dropped here: centred words would sit on it, and the two pictures
   already meet at a clear edge. Below 900px nothing changes: one picture, left copy.
   ============================================================ */
@media (min-width:901px){
  .hero.twin .bg.split{ grid-template-columns:1fr 1fr; }
  .hero.twin .bg.split::before{ display:none; }
  .hero.twin .bg .ph-cap.l{ right:calc(50% + 1.2rem); }
  .hero.twin .bg::after{
    background:
      radial-gradient(ellipse 50% 56% at 50% 52%, rgba(var(--shadow-rgb),.50) 0%, rgba(var(--shadow-rgb),0) 100%),
      linear-gradient(180deg, rgba(var(--shadow-rgb),.55) 0%, rgba(var(--shadow-rgb),0) 22%),
      linear-gradient(0deg, rgba(var(--shadow-rgb),.55) 0%, rgba(var(--shadow-rgb),0) 30%),
      linear-gradient(rgba(var(--shadow-rgb),.62), rgba(var(--shadow-rgb),.62)); }
  .hero.twin .hold-in{ display:flex; justify-content:center; }
  .hero.twin .inner{ max-width:min(64rem,100%); margin-inline:auto; text-align:center; }
  .hero.twin .gold-rule{ margin-inline:auto; }
  .hero.twin .sub{ margin-inline:auto; max-width:54ch; }
  .hero.twin .cta-row{ justify-content:center; }
  .hero.twin .hero-tel{ display:block; text-align:center; }
}

/* ============================================================
   AO R4 (Jon, 4 Oct 2026) measure and space
   1. Photo-and-words sections (.feature-duo, both directions, every page):
      the copy was held to 46ch and the quote card to 56ch, so the words
      stopped well short of their column. They now run the full column, capped
      at a comfortable 64ch for body text so a line never gets tiring.
   2. Fees sections (.feesrow, home page and Acorn House): moved from the
      1300px .hold onto the page-width .w2 container like the sections around
      them, an even two-column split with more air between the columns, and
      the heading and lede allowed to run wider.
   3. Our Care intro: the portrait 4/5 photograph towered over two short
      paragraphs; it is now the 4/3 .wide frame (markup) and the words get a
      little more measure.
   ============================================================ */
.fd-copy .body{ max-width:64ch; }
.fd-copy .qnote{ max-width:none; }
.fd-copy h2{ max-width:none; }
.feesrow{ grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:clamp(2.4rem,6vw,6rem); }
.feesrow .fr-copy h2{ max-width:none; }
.feesrow .fr-copy .lede{ max-width:60ch; }
.feesrow .fr-list{ max-width:64ch; }
.fr-fees .feenote{ max-width:none; }
.about-copy .body{ max-width:60ch; }
@media (max-width:1000px){ .feesrow{ grid-template-columns:minmax(0,1fr); } }
@media (max-width:480px){ .fr-fees .feewrap{ overflow-x:auto; } .fr-fees .feetable th, .fr-fees .feetable td{ white-space:normal; } }

/* ============================================================
   AO R5 (Jon, 6 Oct 2026) the client's own photographs
   .agal: a calm grid of the home's own pictures on the Acorn House page,
   portrait tiles (most of the client's photos are taken upright), four
   across from 901px, two below. Same radius and soft shadow as every other
   framed photograph on the site.
   ============================================================ */
.agal{ margin-top:2.6rem; display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:clamp(.8rem,1.8vw,1.4rem); }
.agal-i{ margin:0; position:relative; border-radius:var(--radius); overflow:hidden; aspect-ratio:3/4; box-shadow:var(--shadow-sm); background:var(--band-tint); }
.agal-i img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
@media (max-width:900px){ .agal{ grid-template-columns:repeat(2,minmax(0,1fr)); } }

/* =====================================================================
   AO R6 - responsive QA pass (6 Oct 2026). Every rule below fixes a fault
   found by measuring the pages at 320-1920px, not by eye.
   ===================================================================== */

/* 1. Photo-and-words sections: the photo's 320px min-height plus its 4:3
      ratio forced it to 427px wide, wider than its grid track between about
      1000 and 1100px, so it ran into the words beside it. The ratio alone
      sizes it properly at every width. */
.fd-photo{ min-height:0; }
.feature-duo > *{ min-width:0; }

/* 2. Fee tables: between 1000 and 1240px the table needed 435px in a 375px
      column, so the Respite prices were cut off. Tighter cells there. */
@media (max-width:1240px){
  .feetable th, .feetable td{ padding:.75rem .7rem; font-size:.93rem; }
  .feetable thead th{ letter-spacing:.06em; }
}
.feesrow > *{ min-width:0; }

/* 3. The 9.7 score card overflowed by 10px on 320px phones. */
@media (max-width:420px){
  .score{ flex-direction:column; align-items:flex-start; }
  .score .st{ min-width:0; }
}

/* 4. Contact page home chooser: two cards side by side were cramped at 390px
      and overflowed at 320px. Phones get one card per row. */
.home-select.two{ grid-template-columns:repeat(2,minmax(0,1fr)); }
@media (max-width:480px){ .home-select.two{ grid-template-columns:1fr; } }

/* 5. Read-next cards: three across from 700px squeezed each title to one
      word per line on tablets. Three across from 1000px; a tidy list below. */
@media (min-width:700px) and (max-width:999px){
  .sx-readnext{ grid-template-columns:1fr; max-width:40rem; }
  .sx-rn{ grid-template-columns:84px 1fr auto; padding:.65rem 1rem .65rem .65rem; }
  .sx-rn-go{ display:block; }
}

/* 6. Review slider dots were 9px targets. The dot stays 9px; the button
      around it is 26px so a finger can hit it. */
.rs-dots{ gap:.15rem; }
.rs-dots button{ width:26px; height:26px; background:transparent; position:relative; }
.rs-dots button::before{ content:""; position:absolute; inset:0; margin:auto; width:9px; height:9px;
  border-radius:50%; background:var(--rule); transition:background .25s var(--ease); }
.rs-dots button[aria-selected="true"]{ background:transparent; }
.rs-dots button[aria-selected="true"]::before{ background:var(--cta); }

/* 7. Mobile menu. On short screens (phones on their side, small phones) the
      bottom of the menu, with the phone numbers and Arrange a visit, sat
      below the screen with no way to reach it. It now scrolls inside itself.
      The burger turns into a cross while the menu is open, and the page you
      are on is marked. */
@media (max-width:1040px){
  .mobile-menu{ max-height:calc(100vh - 96px); max-height:calc(100dvh - 96px); overflow-y:auto;
    overscroll-behavior:contain; -webkit-overflow-scrolling:touch; }
  .mobile-menu a[aria-current="page"]{ color:var(--primary-ink); }
  .mobile-menu a[aria-current="page"]::before{ content:""; display:inline-block; width:6px; height:6px;
    border-radius:50%; background:var(--primary); margin-right:.6rem; vertical-align:middle; }
  .burger span{ transition:transform .25s var(--ease), opacity .2s var(--ease), background .3s; }
  .burger[aria-expanded="true"] span:nth-child(1){ transform:translateY(6px) rotate(45deg); }
  .burger[aria-expanded="true"] span:nth-child(2){ opacity:0; }
  .burger[aria-expanded="true"] span:nth-child(3){ transform:translateY(-6px) rotate(-45deg); }
  .nav.menu-open{ background:var(--surface); border-bottom-color:var(--rule); }
  .nav.menu-open .brand, .nav.menu-open .brand *{ color:var(--ink); }
  .nav.menu-open .burger{ border-color:var(--rule); background:#fff; }
  .nav.menu-open .burger span{ background:var(--ink); }
}

/* 8. A bigger consent tickbox, easier to hit on a phone. */
.consent input{ width:22px; height:22px; accent-color:var(--cta); }

/* 9. Reviews on the home page and Acorn House page: on phones four or more
      full reviews stacked made a wall over 3,000px tall. They now sit in a
      row you swipe through, with the next card peeking in. The Reviews page
      keeps its full list. Cards in the row are always visible (the scroll
      reveal cannot see cards off to the side). */
.rev-hint{ display:none; }
@media (max-width:700px){
  .section:not(.revpage) .reviews{ display:flex; grid-template-columns:none; overflow-x:auto;
    scroll-snap-type:x mandatory; gap:1rem; padding:.4rem .2rem 1.2rem; margin-inline:-.2rem;
    scrollbar-width:none; -webkit-overflow-scrolling:touch; }
  .section:not(.revpage) .reviews::-webkit-scrollbar{ display:none; }
  .section:not(.revpage) .reviews > .review{ flex:0 0 86%; scroll-snap-align:start; opacity:1; transform:none; }
  .section:not(.revpage) .rev-hint{ display:flex; align-items:center; justify-content:center; gap:.45rem;
    margin-top:.4rem; font-size:.88rem; font-weight:700; color:var(--ink-soft); }
  .rev-hint svg{ width:16px; height:16px; }
}
@media (max-width:1240px){ .feetable tbody th{ white-space:normal; } }
@media (max-width:420px){
  .feetable th, .feetable td{ padding:.65rem .5rem; font-size:.88rem; }
  .feetable thead th{ letter-spacing:.02em; font-size:.68rem; }
}
@media (max-width:1240px){
  .fr-fees .feetable tbody th{ white-space:normal; }
  .fr-fees .feetable th, .fr-fees .feetable td{ padding:.75rem .7rem; }
}
@media (max-width:420px){
  .fr-fees .feetable th, .fr-fees .feetable td{ padding:.65rem .45rem; }
  .fr-fees .feetable thead th{ letter-spacing:.02em; font-size:.66rem; }
  .fr-fees .feetable tbody th{ font-size:.9rem; }
  .fr-fees .feetable td{ font-size:.86rem; }
}
