/* =========================================================
   Homeway Mortgages — style.css
   Design system: corporate navy + warm gold accent
   ========================================================= */

:root{
  /* One step below navy-900, and the only place it is used is the far end
     of the CTA band's ground. It exists so that band can go darker than
     the footer without anything else in the palette drifting. */
  --navy-950:#071426;
  --navy-900:#081833;
  --navy-800:#0b2148;
  --navy-700:#12305f;
  --blue-600:#1a4f9c;
  --blue-500:#2469cf;
  --blue-400:#3f86e6;
  --gold-500:#e8a838;
  --gold-400:#f2bd57;
  --ink:#122139;
  --body:#48566d;
  --muted:#7a8598;
  --line:#e5eaf2;
  --bg:#ffffff;
  --bg-soft:#f4f7fc;
  --bg-tint:#eef3fb;
  --white:#ffffff;

  --shadow-sm:0 2px 8px rgba(16,35,66,.06);
  --shadow-md:0 12px 30px rgba(16,35,66,.10);
  --shadow-lg:0 24px 60px rgba(11,33,72,.18);

  --radius:16px;
  --radius-lg:22px;
  --radius-sm:10px;

  --container:1180px;
  --font-head:"Plus Jakarta Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-body:"Inter",system-ui,-apple-system,"Segoe UI",sans-serif;

  --ease:cubic-bezier(.16,.84,.44,1);

  /* Text sitting directly on a photo, with nothing laid over the image.
     Three stacked shadows: a tight one for edge definition, a mid one for
     separation, and a wide low-opacity halo that darkens only the few pixels
     hugging each letter. The halo does the real work over bright areas and
     stays invisible as an effect, because it never forms a visible edge. */
  --on-photo:0 1px 2px rgba(6,14,32,.72),0 2px 10px rgba(6,14,32,.66),0 0 28px rgba(6,14,32,.6),0 0 64px rgba(6,14,32,.5);
  --on-photo-sm:0 1px 2px rgba(6,14,32,.75),0 1px 8px rgba(6,14,32,.66),0 0 22px rgba(6,14,32,.62),0 0 52px rgba(6,14,32,.5);

  /* topbar (42px) + sticky header (81px) — what the hero has to subtract to end
     exactly at the fold */
  --chrome-h:123px;
}

/* ---------- Reset ---------- */
*,*::before,*::after{box-sizing:border-box;margin:0}
/* No overflow-x here on purpose: clipping the root is the usual answer to
   a page that scrolls sideways, but measured on this site it stops the
   sticky header from sticking. The sideways scroll came from the
   off-canvas menu and is fixed at source — see the .nav rule in the
   860px block. */
/* The colour behind the page comes from <html>, not <body>. Without it the
   canvas inherits body's white, and rubber-banding past the end of the page on
   a phone shows a blank white band tacked under the navy footer — the page
   looks like it carries on into an empty section. Navy makes the overscroll
   read as more footer, at both ends of the page. */
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;background:var(--navy-900)}
/* Scroll lock for the off-canvas menu. On the root, not on <body>: body is
   already overflow-x:hidden, and a second overflow on it does not reliably
   stop a touch scroll — the page slid about underneath the open drawer. */
html.is-nav-open{overflow:hidden}
body{
  font-family:var(--font-body);
  color:var(--body);
  background:var(--bg);
  line-height:1.65;
  font-size:16.5px;
  overflow-x:hidden;
}
img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
ul{list-style:none;padding:0}
h1,h2,h3,h4{font-family:var(--font-head);color:var(--ink);line-height:1.15;font-weight:700;letter-spacing:-.02em}
button{font-family:inherit;cursor:pointer}

.container{width:100%;max-width:var(--container);margin:0 auto;padding:0 24px}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.55em;
  font-family:var(--font-head);font-weight:700;font-size:.98rem;
  padding:.9em 1.6em;border-radius:999px;border:2px solid transparent;
  transition:transform .25s var(--ease),box-shadow .25s var(--ease),background .25s,color .25s,border-color .25s;
  white-space:nowrap;line-height:1;
}
.btn svg{width:1.05em;height:1.05em;fill:currentColor}
.btn--primary{background:linear-gradient(135deg,var(--gold-500),var(--gold-400));color:var(--navy-900);box-shadow:0 10px 24px rgba(232,168,56,.35);position:relative;overflow:hidden}
.btn--primary::after{content:"";position:absolute;top:0;left:-90%;width:55%;height:100%;
  background:linear-gradient(105deg,transparent,rgba(255,255,255,.5),transparent);transform:skewX(-20deg);transition:left .55s var(--ease)}
.btn--primary:hover{transform:translateY(-2px);box-shadow:0 16px 32px rgba(232,168,56,.45)}
.btn--primary:hover::after{left:130%}
.btn--outline{background:transparent;border-color:rgba(255,255,255,.55);color:#fff}
.btn--outline:hover{background:rgba(255,255,255,.12);border-color:#fff;transform:translateY(-2px)}
.btn--ghost{background:transparent;border-color:var(--line);color:var(--ink)}
.btn--ghost svg{fill:var(--blue-500)}
.btn--ghost:hover{border-color:var(--blue-500);color:var(--blue-600)}
.btn--sm{padding:.62em 1.15em;font-size:.86rem}
.btn--lg{padding:1.05em 2em;font-size:1.05rem}
.btn--block{width:100%}

/* ---------- Eyebrow ---------- */
.eyebrow{
  display:inline-flex;align-items:center;gap:.5em;
  font-family:var(--font-head);font-weight:700;font-size:.73rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--blue-600);background:var(--bg-tint);padding:.5em 1em;border-radius:999px;margin-bottom:1.1rem;
}
.eyebrow svg{width:1.1em;height:1.1em;fill:var(--gold-500)}
.eyebrow--light{color:#cfe0ff;background:rgba(255,255,255,.10)}
.eyebrow--light svg{fill:var(--gold-400)}

/* ---------- Top bar ---------- */
.topbar{background:var(--navy-900);color:#c6d3e8;font-size:.85rem}
.topbar__inner{display:flex;align-items:center;justify-content:space-between;min-height:42px;gap:16px}
.topbar__contact{display:flex;align-items:center;gap:22px;flex-wrap:wrap}
.topbar__item{display:inline-flex;align-items:center;gap:.5em;color:#c6d3e8;transition:color .2s}
.topbar__item:hover{color:#fff}
.topbar__item svg{width:15px;height:15px;fill:var(--gold-400)}
.topbar__social{display:flex;gap:8px}
.topbar__social a{width:28px;height:28px;display:grid;place-items:center;border-radius:50%;background:rgba(255,255,255,.08);transition:background .2s,transform .2s}
.topbar__social a:hover{background:var(--gold-500);transform:translateY(-2px)}
.topbar__social svg{width:15px;height:15px;fill:#fff}

/* ---------- Header (dark) ---------- */
.header{position:sticky;top:0;z-index:100;background:rgba(9,24,52,.86);backdrop-filter:blur(14px);border-bottom:1px solid rgba(255,255,255,.08);
  transition:box-shadow .3s,background .3s,transform .4s var(--ease)}
/* Past the halfway point of the page the bar slides up and out. Transform only,
   so it never takes layout with it — nothing below shifts when it goes. */
.header.is-gone{transform:translateY(-100%)}
.header.is-stuck{background:rgba(8,20,44,.96);box-shadow:0 8px 30px rgba(0,0,0,.28)}
.header__inner{display:flex;align-items:center;justify-content:space-between;min-height:80px;gap:20px}
/* The top chrome runs narrower than the page body, so space-between stops
   pushing the logo and the menu to opposite edges — the gap between them drops
   from 252px to 74px. The topbar has to come along: it sits directly above the
   header, and narrowing only one would indent the logo 90px from the phone
   number above it. Both stay centred, so nothing else moves. */
.topbar__inner,.header__inner{max-width:1000px}

/* flex:none on both the link and the image.
   .header__inner is a flex row and .brand was the only item in it with the
   default `flex:0 1 auto`, so when the nav asked for more width the brand
   was what gave way — the logo kept its 56px height and lost width, which
   reads as a squashed, compressed mark. A logo is never the element that
   yields; the nav shrinks, or the layout goes to the mobile menu.
   height + width:auto keeps the aspect ratio in the image's own hands —
   no aspect-ratio property, which would fight the pair and win. */
.brand{display:inline-flex;align-items:center;flex:none}
.brand__logo{height:56px;width:auto;max-width:none;flex:none;display:block}

.nav{display:flex;align-items:center;gap:22px}
.nav__list{display:flex;align-items:center;gap:2px}
.nav__link{
  display:inline-flex;align-items:center;gap:.3em;
  font-family:var(--font-head);font-weight:600;font-size:.95rem;color:#e7edf7;
  padding:.6em .8em;border-radius:10px;transition:color .2s,background .2s;position:relative;
}
.nav__link:hover{color:#fff;background:rgba(255,255,255,.08)}
.nav__link.is-active{color:var(--gold-400)}
.nav__link.is-active::after{content:"";position:absolute;left:.8em;right:.8em;bottom:.3em;height:2px;border-radius:2px;background:var(--gold-500)}
/* flex:none is load-bearing. .nav__link is inline-flex and the label
   takes the space first, so without it the caret shrank from its
   declared 14px to about 3px — a 24×24 chevron drawn into a 3×14 box,
   which reads as a vertical smudge beside the menu word rather than an
   arrow. Never let an icon be the flex item that gives way. */
.nav__caret{flex:none;width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;transition:transform .25s}
.nav__item--has{position:static}
.nav__item--has:hover .nav__caret,
.nav__item--has:focus-within .nav__caret,
.nav__item--has.is-open .nav__caret{transform:rotate(180deg)}

/* Floating mega panel — compact, centred under the sticky header, rounded corners */
.nav__mega{
  position:absolute;top:calc(100% + 14px);left:50%;
  width:min(768px,calc(100% - 48px));
  background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);
  opacity:0;visibility:hidden;transform:translate(-50%,10px);
  transition:opacity .24s var(--ease),transform .24s var(--ease),visibility .24s;
}
.nav__mega--wide{width:min(800px,calc(100% - 48px))}
/* Invisible bridge over the 14px gap so the pointer can travel to the panel */
.nav__mega::before{content:"";position:absolute;left:0;right:0;top:-14px;height:14px}
.nav__item--has:hover .nav__mega,
.nav__item--has:focus-within .nav__mega,
.nav__item--has.is-open .nav__mega{opacity:1;visibility:visible;transform:translate(-50%,0)}
.nav__mega-inner{padding:28px 26px 24px;display:grid;grid-template-columns:1fr 1fr 1.26fr;gap:22px;text-align:left}
.nav__mega-inner--wide{grid-template-columns:1.27fr 1fr 1.3fr}
.nav__mega-grp{display:flex;align-items:center;gap:.6em;margin:0 0 12px;font-family:var(--font-head);font-size:.72rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--muted);white-space:nowrap}
.nav__mega-grp::after{content:"";height:1px;flex:1;background:var(--line)}
.nav__mega-grp--gap{margin-top:24px}
.nav__mega-item{display:flex;align-items:center;gap:.6em;padding:.42em .55em;margin-left:-.55em;border-radius:10px;font-weight:500;font-size:.92rem;color:var(--body);transition:background .18s,color .18s,transform .18s}
.nav__mega-item + .nav__mega-item{margin-top:3px}
.nav__mega-item:hover{background:var(--bg-tint);color:var(--blue-600);transform:translateX(2px)}
.nav__mega-ic{width:28px;height:28px;padding:6px;flex:none;fill:none;stroke:var(--gold-500);stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;
  border-radius:8px;background:rgba(232,168,56,.13);box-shadow:inset 0 0 0 1px rgba(232,168,56,.18);transition:background .18s,stroke .18s}
.nav__mega-item:hover .nav__mega-ic{background:var(--gold-500);stroke:#fff}
.nav__mega-feat{background:linear-gradient(135deg,var(--navy-800),var(--navy-700));border-radius:var(--radius);padding:18px;color:#c6d3e8;display:flex;flex-direction:column;align-items:flex-start;gap:9px}
.nav__mega-feat h4{color:#fff;font-size:1rem;line-height:1.35}
.nav__mega-feat p{font-size:.84rem;line-height:1.5}
.nav__mega-feat .btn{margin-top:3px}
.nav__mega-tel{display:inline-flex;align-items:center;gap:.5em;color:#fff;font-weight:600;font-size:.88rem}
.nav__mega-tel svg{width:15px;height:15px;fill:var(--gold-400)}
.nav__mega-tel:hover{color:var(--gold-400)}
.nav__mega-bottom{border-top:1px solid var(--line);background:var(--bg-soft);border-radius:0 0 var(--radius-lg) var(--radius-lg)}
.nav__mega-bottom-inner{padding:11px 26px;display:flex;justify-content:space-between;align-items:center;gap:18px;flex-wrap:wrap;font-size:.82rem;color:var(--muted)}
.nav__mega-bottom-inner a{color:var(--blue-600);font-weight:600;white-space:nowrap}
.nav__mega-bottom-inner a:hover{text-decoration:underline}
.nav__cta{display:flex;align-items:center;gap:12px}
.nav__cta .btn--ghost{background:transparent;border-color:rgba(255,255,255,.22);color:#e7edf7}
.nav__cta .btn--ghost svg{fill:var(--gold-400)}
.nav__cta .btn--ghost:hover{border-color:var(--gold-400);color:#fff;background:rgba(255,255,255,.06)}

/* Drawer chrome — the sticky bar, its close button and the call block at the
   foot of the panel. All three exist only inside the off-canvas menu, so they
   stay out of the way until the 860px block turns them on. */
.nav__bar{display:none}
.nav__tel{display:none}
.nav-scrim{display:none}

.hamburger{display:none;width:46px;height:46px;border:1px solid rgba(255,255,255,.2);border-radius:12px;background:rgba(255,255,255,.06);flex-direction:column;align-items:center;justify-content:center;gap:5px}
.hamburger span{width:22px;height:2.4px;background:#fff;border-radius:2px;transition:transform .3s,opacity .3s}
.hamburger.is-open span:nth-child(1){transform:translateY(7.4px) rotate(45deg)}
.hamburger.is-open span:nth-child(2){opacity:0}
.hamburger.is-open span:nth-child(3){transform:translateY(-7.4px) rotate(-45deg)}

/* ---------- Hero ---------- */
/* Full first screen: the viewport minus the topbar and the sticky header, so the
   hero ends exactly where the fold is. svh (not vh) keeps mobile browsers from
   counting the collapsing address bar and pushing the hero past the fold. */
.hero{position:relative;color:#fff;overflow:hidden;background:var(--navy-900);
  display:grid;align-content:center;
  min-height:calc(100vh - var(--chrome-h,122px));
  min-height:calc(100svh - var(--chrome-h,122px))}
.hero__bg{position:absolute;inset:0;z-index:0;overflow:hidden}

/* Four photos crossfading on a 32s loop — 8s each, ~1s of overlap. The first
   slide carries a negative delay so it is already at full opacity on the very
   first frame, instead of fading up out of an empty navy box. */
.hero__slide{position:absolute;inset:0;background-position:center 55%;background-size:cover;background-repeat:no-repeat;
  opacity:0;animation:heroFade 32s linear infinite,heroZoom 32s ease-in-out infinite}
/* Running order: home-3 → home-2 → home-4 → home-1 — adviser handshake, family
   outside a sold house, contract signed, moving in. If you reorder these, move
   the preload in build/build.js to whichever photo lands first. */
.hero__slide:nth-child(1){animation-delay:-1s,-1s;background-position:center 60%;
  background-image:image-set(url("../img/hero/home-3.webp") type("image/webp"),url("../img/hero/home-3.jpg") type("image/jpeg"))}
.hero__slide:nth-child(2){animation-delay:7s,7s;
  background-image:image-set(url("../img/hero/home-2.webp") type("image/webp"),url("../img/hero/home-2.jpg") type("image/jpeg"))}
.hero__slide:nth-child(3){animation-delay:15s,15s;background-position:center 50%;
  background-image:image-set(url("../img/hero/home-4.webp") type("image/webp"),url("../img/hero/home-4.jpg") type("image/jpeg"))}
.hero__slide:nth-child(4){animation-delay:23s,23s;
  background-image:image-set(url("../img/hero/home-1.webp") type("image/webp"),url("../img/hero/home-1.jpg") type("image/jpeg"))}
@keyframes heroFade{0%{opacity:0}3%{opacity:1}25%{opacity:1}28%{opacity:0}100%{opacity:0}}
@keyframes heroZoom{from{transform:scale(1.02)}to{transform:scale(1.1)}}
/* Single centred column: title, lead and the two buttons, nothing else.
   Nothing is laid over the photo — legibility comes from --on-photo on the type. */
/* extra bottom padding keeps the centred block clear of the benefit cards,
   which are pulled up over the hero's last 56px */
.hero__inner{position:relative;z-index:1;display:grid;justify-items:center;text-align:center;
  padding:72px 24px 148px}
.hero__title{font-size:clamp(2.12rem,4.23vw,3.38rem);color:#fff;font-weight:800;margin-bottom:1rem;
  text-shadow:var(--on-photo)}
.hero__title span{color:var(--gold-400);display:inline-block}
/* was #c9d6ec at 400 — too thin and too dim to survive on a bright photo once
   nothing is laid over it. Heavier strokes hold a shadow far better than a
   bigger blur does, and they don't smudge the way a wide halo on thin type does. */
.hero__lead{font-size:1.2rem;font-weight:500;color:#eef3fc;max-width:34em;margin:0 auto 2rem;
  text-shadow:var(--on-photo-sm)}
.hero__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:14px}
/* the ghost button has no fill of its own, so its label and border need the
   same treatment or they dissolve into a bright patch of the picture */
.hero__actions .btn--outline{text-shadow:var(--on-photo-sm);
  background:rgba(6,14,32,.3);border-color:rgba(255,255,255,.75);
  box-shadow:0 2px 18px rgba(6,14,32,.35)}
.hero__actions .btn--outline:hover{background:rgba(6,14,32,.5)}

/* Hero quote card */
.hero__card{position:relative;z-index:1}
.quote-card{background:#fff;border-radius:var(--radius-lg);padding:30px;box-shadow:var(--shadow-lg);color:var(--body)}
.quote-card__title{font-size:1.45rem;margin-bottom:.35rem}
.quote-card__sub{font-size:.95rem;color:var(--muted);margin-bottom:1.4rem}
.quote-card__form{display:grid;gap:14px}
.quote-card__note{font-size:.78rem;color:var(--muted);text-align:center;margin-top:.2rem}

/* ---------- Fields ---------- */
.field{display:grid;gap:.4rem}
.field label{font-family:var(--font-head);font-weight:600;font-size:.85rem;color:var(--ink)}
.field input,.field select,.field textarea{
  width:100%;padding:.85em 1em;border:1.5px solid var(--line);border-radius:12px;
  font-family:inherit;font-size:.98rem;color:var(--ink);background:var(--bg-soft);transition:border-color .2s,box-shadow .2s,background .2s;
}
/* iOS Safari zooms the whole page in when a focused field is under 16px,
   and it does not zoom back out afterwards — the visitor is left panning
   a magnified form. .98rem is 15.7px, which trips it. 16px exactly on
   touch widths; the 0.3px difference is not visible, the zoom is. */
@media (max-width:860px){
  .field input,.field select,.field textarea{font-size:16px}
}
.field textarea{resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--blue-500);background:#fff;box-shadow:0 0 0 4px rgba(36,105,207,.12)}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:14px}

/* ---------- Benefits ---------- */
.benefits{margin-top:-56px;position:relative;z-index:5}
.benefits__grid{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
/* align-content:start matters. The cards stretch to the tallest sibling, and
   with the default (stretch) the leftover height is handed to the auto rows —
   in the card with the shortest text row 1 grew from 50px to 62px, pushing its
   centred icon and title 6px below the other three. Extra space now collects
   at the bottom of the card, where it is invisible. */
/* The hairline border is not decoration. These cards overlap the hero by 56px,
   and the hero is now a slideshow — on the darker frames a navy card would lose
   its edge against the photo. 10% white keeps the outline on every frame.
   align-content:start matters too: the cards stretch to the tallest sibling,
   and with the default (stretch) the leftover height is handed to the auto
   rows — in the card with the shortest text row 1 grew from 50px to 62px and
   pushed its centred icon and title 6px below the other three. */
.benefit{background:linear-gradient(150deg,var(--navy-700),var(--navy-800));
  border:1px solid rgba(255,255,255,.10);border-radius:var(--radius);padding:26px 24px;
  box-shadow:0 16px 38px rgba(6,16,38,.34);transition:transform .3s var(--ease),box-shadow .3s;
  display:grid;grid-template-columns:auto 1fr;column-gap:14px;align-content:start}
.benefit:hover{transform:translateY(-6px);box-shadow:0 26px 56px rgba(6,16,38,.44)}
/* one step lighter ground swallows a 9% white tile, so the icon well is lifted
   to keep the same separation it had on the darker card */
.benefit__icon{grid-column:1;grid-row:1;align-self:center;width:50px;height:50px;display:grid;place-items:center;border-radius:13px;background:rgba(255,255,255,.13)}
/* blue #1a4f9c has nothing left on navy — gold is the only palette colour that
   survives there, and it matches the step medallions */
.benefit__icon svg{width:26px;height:26px;fill:var(--gold-400)}
.benefit h3{grid-column:2;grid-row:1;align-self:center;font-size:1.16rem;margin:0;color:#fff}
.benefit p{grid-column:1 / -1;grid-row:2;font-size:.94rem;margin-top:14px;color:#b9c8e0}

/* ---------- Sections ---------- */
.section{padding:92px 0}
.section--tint{background:var(--bg-soft)}
/* two stacked sections with the same background have no visual boundary between
   them — collapse the second one's top padding so the gap stays one rhythm unit */
.section--tint + .section--tint,
.section:not(.section--tint) + .section:not(.section--tint){padding-top:0}
/* A single-sentence subtitle should sit on one line when the width is there.
   At 640px "Real recommendations from real clients — straight from Facebook,
   word for word." broke after "for", stranding "word." alone on a second line
   — a hand-picked max-width creating a break the page had room to avoid. The
   cap is now set from the longest subtitle on the site rather than guessed. */
.section__head{max-width:880px;margin:0 auto 52px;text-align:center}
.section__head h2{font-size:clamp(1.33rem,2.38vw,1.93rem);margin-bottom:.7rem}
.section__head h2::after{content:"";display:block;width:54px;height:3px;border-radius:2px;margin:16px auto 0;
  background:linear-gradient(90deg,var(--gold-500),var(--gold-400))}
.section__head p{font-size:1.08rem;color:var(--muted)}
/* left-aligned gold accent for split sections */
.why__content h2::after,.about__text h2::after,.team__body h2::after{content:"";display:block;width:54px;height:3px;border-radius:2px;margin:16px 0 0;
  background:linear-gradient(90deg,var(--gold-500),var(--gold-400))}

/* ---------- Cards grid ---------- */
.cards{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
.card{
  background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:26px 24px;
  transition:transform .3s var(--ease),box-shadow .3s,border-color .3s;position:relative;
  display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto 1fr auto;column-gap:15px;
}
.card:hover{transform:translateY(-6px);box-shadow:var(--shadow-lg);border-color:transparent}
.card::before{content:"";position:absolute;top:-1px;left:-1px;right:-1px;height:3px;border-radius:var(--radius) var(--radius) 0 0;
  background:linear-gradient(90deg,var(--gold-500),var(--gold-400));transform:scaleX(0);transform-origin:left;transition:transform .4s var(--ease)}
.card:hover::before{transform:scaleX(1)}
.card__icon{grid-column:1;grid-row:1;align-self:center;width:50px;height:50px;display:grid;place-items:center;border-radius:13px;
  background:linear-gradient(140deg,var(--blue-600),var(--navy-800));transition:transform .3s}
.card:hover .card__icon{transform:scale(1.06) rotate(-3deg)}
.card__icon svg{width:26px;height:26px;fill:none;stroke:var(--gold-400);stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.card h3{grid-column:2;grid-row:1;align-self:center;font-size:1.14rem;margin:0}
.card p{grid-column:1 / -1;grid-row:2;font-size:.92rem;color:var(--body);margin-top:14px}
.card__link{grid-column:1 / -1;grid-row:3;margin-top:14px;font-family:var(--font-head);font-weight:700;font-size:.9rem;color:var(--blue-600);transition:transform .3s var(--ease),color .2s}
.card:hover .card__link{transform:translateX(5px);color:var(--gold-500)}
.card--soft .card__icon{background:var(--bg-tint)}
.card--soft .card__icon svg{stroke:var(--blue-600)}

/* ---------- Full-bleed photo card ----------
   The base .card is a three-row grid with padding and a border; this variant
   undoes all of that and becomes a flex column that pins its body to the
   bottom. Aspect-ratio (not a fixed height) keeps every card equal without
   caring what the copy length is, and reserves the space before the photo
   arrives, so nothing jumps as images decode.

   The gradient has to be calibrated for the *lightest* photo in the set — the
   calculator on pale wood — because one scrim serves all of them. That makes it
   heavier than the darkest photo strictly needs; the trade is deliberate, since
   unreadable copy on one card is worse than a slightly veiled photo on another. */

/* ---------- Horizontal rail (home) ----------
   Base state — and the state anyone gets without JS, on touch widths, on a
   viewport too short to pin into, or under reduced motion — is a plain
   horizontal strip you scroll or swipe. main.js upgrades it to .rail--pinned
   on wide pointers, where the stage sticks and the row travels left→right
   with the page scroll before releasing to the next section. */
.rail{padding:0}                       /* the stage carries the vertical rhythm */
.rail__track{position:relative}
.rail__stage{padding:92px 0}
.rail .section__head{margin-bottom:40px}

.rail__viewport{overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;scrollbar-width:none;-ms-overflow-style:none}
.rail__viewport::-webkit-scrollbar{display:none}
/* padding-block clears the -6px hover lift and the card shadow, which would
   otherwise be sliced off by the viewport's overflow */
.cards--rail{display:flex;gap:22px;width:max-content;padding-block:14px;
  padding-inline:var(--rail-lead,24px)}
.cards--rail>.card{flex:0 0 var(--rail-card,min(78vw,320px));width:var(--rail-card,min(78vw,320px));
  scroll-snap-align:start;
  /* the reveal stagger is set inline per index; a row that arrives one card at
     a time doesn't want it, the delay reads as lag */
  transition-delay:0ms!important}

.rail--pinned .rail__stage{position:sticky;top:0;min-height:100vh;min-height:100svh;
  display:flex;flex-direction:column;justify-content:center;padding:calc(80px + 44px) 0 44px}
/* Cards leaving the stage fade at the page edge instead of being sliced by it.
   The fade sits in the first/last 34px, well outside the container lead, so at
   rest nothing on screen is touched. */
.rail--pinned .rail__viewport{overflow:hidden;scroll-snap-type:none;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 34px,#000 calc(100% - 34px),transparent);
  mask-image:linear-gradient(90deg,transparent,#000 34px,#000 calc(100% - 34px),transparent)}
.rail--pinned .cards--rail{will-change:transform}

.rail__foot{display:flex;align-items:center;gap:20px;margin-top:34px}
.rail__progress{position:relative;flex:1;height:3px;border-radius:2px;background:var(--line)}
.rail__progress i{position:absolute;top:0;bottom:0;left:0;width:25%;border-radius:2px;
  background:linear-gradient(90deg,var(--gold-500),var(--gold-400))}
/* flex:0 0 auto — a nowrap label that is allowed to shrink gets its text
   clipped on narrow screens; the progress bar gives up the room instead */
.rail__cue{display:inline-flex;flex:0 0 auto;align-items:center;gap:9px;white-space:nowrap;
  font-family:var(--font-head);font-weight:700;font-size:.78rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted);transition:opacity .35s var(--ease)}
.rail.is-travelling .rail__cue{opacity:0}
.rail__cue-scroll{display:none}
.rail--pinned .rail__cue-scroll{display:inline}
.rail--pinned .rail__cue-swipe{display:none}
/* padding-right reserves the 5px the arrow travels, so the nudge can never
   push the row wider than its own box */
.rail__cue-arrow{width:17px;height:17px;margin-right:5px;fill:none;stroke:var(--gold-500);stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;animation:railNudge 1.9s var(--ease) infinite}
@keyframes railNudge{0%,100%{transform:translateX(0)}50%{transform:translateX(5px)}}

/* Duotone coloured service icons (no tile, own fills) */
.card__icon--duo{width:60px;height:60px;border-radius:16px;display:grid;place-items:center;
  background:linear-gradient(158deg,#ffffff,#eef2f8);border:1px solid var(--line);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9),0 8px 18px rgba(16,35,66,.10);
  transition:transform .35s var(--ease),box-shadow .35s,border-color .35s}
.card--soft .card__icon--duo{background:linear-gradient(158deg,#ffffff,#eef2f8)}
.card__icon--duo svg{width:38px;height:38px;fill:#000;stroke:none;stroke-width:0;filter:drop-shadow(0 2px 3px rgba(16,35,66,.16))}
.card:hover .card__icon--duo{transform:translateY(-3px);border-color:var(--gold-400);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9),0 14px 26px rgba(232,168,56,.24)}

/* ---------- Living icons: parts inside the SVGs move on their own.
   ai-* classes are assigned per element in build/icons-duo.js.
   Gentle idle loop; speeds up while the card is hovered. ---------- */
.card__icon--duo [class*="ai-"]{
  transform-box:fill-box;transform-origin:center;
  animation-duration:var(--ai-dur,3.2s);animation-timing-function:ease-in-out;animation-iteration-count:infinite;
}
.card:hover .card__icon--duo{--ai-dur:1.2s}
/* natural desync between neighbouring cards */
.cards .card:nth-child(2n) [class*="ai-"]{animation-delay:.5s}
.cards .card:nth-child(3n) [class*="ai-"]{animation-delay:1s}
.ai-delay{animation-delay:1.4s!important}

.ai-spin{animation-name:hwSpin;animation-timing-function:linear;animation-duration:var(--ai-dur,5s)}
.ai-wiggle{animation-name:hwWiggle}
.ai-bob{animation-name:hwBob;animation-duration:var(--ai-dur,2.6s)}
.ai-beat{animation-name:hwBeat;animation-duration:var(--ai-dur,2.2s);transform-origin:50% 60%}
.ai-pulse{animation-name:hwPulse;animation-duration:var(--ai-dur,2.6s)}
.ai-flash{animation-name:hwFlash;animation-duration:var(--ai-dur,2.4s)}
.ai-glow{animation-name:hwGlow}
.ai-shift-r{animation-name:hwShiftR;animation-duration:var(--ai-dur,2.4s)}
.ai-shift-l{animation-name:hwShiftL;animation-duration:var(--ai-dur,2.4s)}
.ai-nudge-ne{animation-name:hwNudgeNE;animation-duration:var(--ai-dur,2.4s)}
.ai-hoist{animation-name:hwHoist;animation-duration:var(--ai-dur,2.8s)}
.ai-sway{animation-name:hwSway;transform-origin:50% 100%}

@keyframes hwSpin{to{transform:rotate(360deg)}}
@keyframes hwWiggle{0%,100%{transform:rotate(0)}30%{transform:rotate(-10deg)}70%{transform:rotate(10deg)}}
@keyframes hwBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-1.4px)}}
@keyframes hwBeat{0%,26%,52%,100%{transform:scale(1)}10%{transform:scale(1.16)}38%{transform:scale(1.1)}}
@keyframes hwPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.1)}}
@keyframes hwFlash{0%,32%,100%{opacity:1}10%{opacity:.3}20%{opacity:1}26%{opacity:.55}}
@keyframes hwGlow{0%,100%{opacity:1}50%{opacity:.4}}
@keyframes hwShiftR{0%,100%{transform:translateX(0)}50%{transform:translateX(1.5px)}}
@keyframes hwShiftL{0%,100%{transform:translateX(0)}50%{transform:translateX(-1.5px)}}
@keyframes hwNudgeNE{0%,100%{transform:translate(0,0)}50%{transform:translate(1.4px,-1.4px)}}
@keyframes hwHoist{0%,100%{transform:translateY(0)}50%{transform:translateY(-2.4px)}}
@keyframes hwSway{0%,100%{transform:rotate(-5deg)}50%{transform:rotate(5deg)}}

/* ---------- Why us ---------- */
.why{padding:96px 0;background:linear-gradient(180deg,#fff,var(--bg-soft))}
.why__inner{display:grid;grid-template-columns:1.1fr .9fr;gap:56px;align-items:center}

/* Home only — the hub pages keep the two-column form above, which is why these
   rules are scoped to the .why section rather than rewriting .why__inner.

   The two columns used to be centred against each other, and with a 646px left
   column against a 301px right one that left 173px of nothing above the figures
   and another 173px below: 346px of dead space, more than the height of the
   column it surrounded. Now the copy and the checklist share the top row and
   the four figures run the full width underneath, where they read as a band of
   proof rather than a block stranded to one side. */
.why .why__inner{grid-template-columns:1fr;gap:46px;align-items:stretch}
.why__top{display:grid;grid-template-columns:1.05fr .95fr;gap:56px;align-items:start}
.why__top .checklist{margin-bottom:0}
.why .why__stats{grid-template-columns:repeat(4,1fr)}
.why__content h2{font-size:clamp(1.33rem,2.38vw,1.89rem);margin-bottom:.6rem}
.why__lead{font-size:1.12rem;color:var(--muted);margin-bottom:1.8rem}
.checklist{display:grid;gap:16px;margin-bottom:2rem}
.checklist li{position:relative;padding-left:44px;font-size:.96rem;color:var(--body)}
.checklist li span{display:block;font-family:var(--font-head);font-weight:700;color:var(--ink);font-size:1.02rem;margin-bottom:.1rem}
.checklist li::before{content:"";position:absolute;left:0;top:2px;width:28px;height:28px;border-radius:8px;
  background:var(--bg-tint) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231a4f9c' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/16px no-repeat}
.why__actions{display:flex;align-items:center;gap:22px;flex-wrap:wrap}
/* The phone number sits next to the gold primary in three places on light
   ground — "Why Homeway" on home, the same block on About, and the team card.
   It now carries a button shell so it reads as a control rather than a line of
   text: same padding, size and border width as .btn--lg, so the two sit on one
   baseline instead of the number being 27px against the button's 56px.

   The border is #6a8dc1, not the tint's own #cfdcef. A control outlined only by
   a line has to clear 3:1 against what surrounds it, and against this near-white
   section the soft blue measured 1.4:1 — the fill behind it only 1.1:1, so
   neither edge was doing the job. Walking a blue-grey ramp against the measured
   background, #7596c6 is the first step to clear 3:1; this is one step darker
   for margin, and still far lighter than the navy of a solid secondary button. */
.phone-inline{display:inline-flex;align-items:center;justify-content:center;gap:.5em;
  font-family:var(--font-head);font-weight:700;color:var(--ink);font-size:1.05rem;line-height:1;
  padding:1.05em 2em;border:2px solid #6a8dc1;border-radius:999px;background:var(--bg-tint);
  white-space:nowrap;
  transition:transform .25s var(--ease),background .25s,border-color .25s,color .25s}
.phone-inline:hover{background:#e2ebf9;border-color:var(--blue-500);color:var(--blue-600);transform:translateY(-2px)}
.phone-inline svg{width:20px;height:20px;fill:var(--blue-600)}

.why__stats{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.stat{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:28px 24px;box-shadow:var(--shadow-sm);text-align:center}
.stat strong{display:block;font-family:var(--font-head);font-size:2.6rem;font-weight:800;color:var(--blue-600);line-height:1}
.stat span{font-size:.9rem;color:var(--muted);margin-top:.4rem;display:block}
.stat:nth-child(2) strong,.stat:nth-child(3) strong{color:var(--gold-500)}

/* ---------- Lenders marquee ---------- */
/* Same ground as the benefit cards — navy-700 into navy-800. The edge fade is an
   alpha mask, not a colour-matched overlay, so it keeps working over a gradient. */
.lenders{background:linear-gradient(150deg,var(--navy-700),var(--navy-800));padding:44px 0;overflow:hidden}
.lenders__title{text-align:center;color:#aebdd6;font-family:var(--font-head);font-weight:600;font-size:1.02rem;margin-bottom:24px}
/* The strip shows twelve marks against a "90+" claim made in three other
   places on the site. Lifting the figure ties the sample to the number. */
.lenders__title strong{color:#e7edf7;font-weight:600}
/* Fade the strip into the navy at both edges so tiles don't get clipped mid-logo.
   The element is full-bleed and clips its own overflow: masking a container-width
   box instead lets the gradient tile across the overflowing track (mask-repeat
   defaults to repeat), which slices fade bands straight through the tiles. */
/* The vertical padding is not decoration: the viewport clips on both axes
   (it has to, to hide the marquee overflow), and .lender:hover lifts a tile
   by 3px. Without room above, the lift pushes the tile's top edge — gold
   border included — straight through the clip. Negative margin cancels the
   padding so the band's own rhythm is unchanged. The mask is a horizontal
   gradient, so the taller box doesn't affect the edge fades. */
.lenders__viewport{position:relative;overflow:hidden;padding:8px 0;margin:-8px 0;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-size:100% 100%;mask-size:100% 100%}
/* wider gap than before: the tiles are smaller now, and the air between them
   does the separating that the tile edges used to do */
.lenders__track{--lender-gap:18px;display:flex;gap:var(--lender-gap);width:max-content;animation:marquee 45s linear infinite}
/* A light tile, because the logos are in their real brand colours and every
   one of them is drawn for a light background. On the navy, half the set
   (Coventry, Nationwide, NatWest, Lloyds) is dark-on-transparent and would
   simply disappear.

   Not pure white, though: #fff against this navy measures 17.7:1, near the
   21:1 ceiling, and the row read as twelve lamps rather than twelve lenders.
   At 88% the navy underneath tints the tile to roughly #e1e3e7 and the ratio
   drops to 13.7:1 — still far more than any logo needs, but the glare is gone.
   Composing it from the background rather than hard-coding the tint means the
   tiles re-tune themselves if the band's colour ever changes.

   The border stays in the box at 1px transparent: it carries the gold hover
   state, and dropping it outright would shift every tile by 2px on hover.

   The box is also tighter than it was — 150x58 instead of 164x68, with the mark
   capped at 38px instead of 34px. Dimming the white only addresses how bright
   it is; shrinking the box addresses how much of the band is white at all. The
   mark went from filling half the tile's height to two thirds, so the lenders
   are what you see rather than the boxes they sit in. --logo-cap is a variable
   because the cap has to shrink with the tile on small screens, or the mark
   overflows a content box shorter than itself. */
.lender{--logo-cap:38px;
  flex:0 0 auto;display:grid;place-items:center;width:150px;height:58px;padding:9px 14px;
  background:rgba(255,255,255,.88);border:1px solid transparent;border-radius:14px;
  box-shadow:0 3px 12px rgba(2,10,25,.32);
  transition:transform .3s var(--ease),box-shadow .3s,border-color .3s,background .3s}
/* Cap by height, not by percentage of the box: lender marks arrive at wildly
   different aspect ratios (a 9:1 wordmark next to a 1:1 symbol) and a shared
   height cap is what makes a logo wall read as one row. Long wordmarks then
   hit the width limit first and sit shorter, which is correct — they carry
   their weight horizontally. --logo-scale (build/lenders.js) trims the
   outliers that still read heavy. */
.lender img{max-width:100%;max-height:calc(var(--logo-cap) * var(--logo-scale,1));
  width:auto;height:auto;object-fit:contain;display:block}
/* hover lifts the tile back towards full white, so the row still answers the
   pointer now that the resting state is dimmer */
.lender:hover{transform:translateY(-3px);border-color:var(--gold-400);
  background:rgba(255,255,255,.97);
  box-shadow:0 10px 22px rgba(2,10,25,.36)}

/* Escape hatch: add `lenders--mono` to the section (build/lenders.js →
   TREATMENT) to get the previous look — glass tiles on navy with every mark
   forced to white. Useful if the client ever prefers the quieter row, or if
   an approved logo pack arrives as reversed artwork only. Note that a mark
   whose detail is knocked out of a solid shape flattens into a blob under
   the filter; see the note in build/lenders.js. */
.lenders--mono .lender{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.13);
  box-shadow:none;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
.lenders--mono .lender img{filter:brightness(0) invert(1);opacity:.8;transition:opacity .3s}
.lenders--mono .lender:hover{background:rgba(255,255,255,.1);box-shadow:none}
.lenders--mono .lender:hover img{opacity:1}
/* Half the track is one full set; the extra half-gap lands the loop
   exactly on the seam so there is no visible jump on repeat */
@keyframes marquee{from{transform:translateX(0)}to{transform:translateX(calc(-50% - var(--lender-gap) / 2))}}
.lenders:hover .lenders__track{animation-play-state:paused}
/* the cap comes down with the tile — 38px would overflow a 36px content box */
@media (max-width:640px){.lender{--logo-cap:34px;width:132px;height:52px;padding:8px 12px}.lenders__track{--lender-gap:14px}}
/* No motion: drop the duplicate pass and lay the panel out as a static grid */
@media (prefers-reduced-motion:reduce){
  .lenders__viewport{-webkit-mask-image:none;mask-image:none}
  .lenders__track{animation:none;width:auto;flex-wrap:wrap;justify-content:center}
  .lender--dup{display:none}
}

/* ---------- Steps ---------- */
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
/* Full-bleed photo cards, same as services and values — the shared rules live
   further down, after .value. Only the step badge is specific to this section.

   The dotted connector that used to run between cards is gone on purpose, not
   by omission: it linked medallion to medallion along the photo/body seam, and
   with the seam gone there is no shared line for it to sit on. A connector
   drawn between four badges that are not aligned to each other reads as a
   stray mark rather than a path. */
.step__num{position:absolute;top:16px;left:16px;z-index:3;
  display:inline-flex;align-items:center;padding:.4em .85em;border-radius:999px;
  font-family:var(--font-head);font-weight:700;font-size:.76rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--navy-900);background:linear-gradient(135deg,var(--gold-500),var(--gold-400));
  box-shadow:0 4px 12px rgba(8,24,51,.3)}

/* ---------- Reviews ---------- */
.reviews{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}

/* ---------- Reviews marquee (home + about) ----------
   Full-bleed and clipping its own overflow, so the edge fades land on the page
   edge rather than the container edge — masking a container-width box instead
   lets the gradient tile across the overflow and slice fade bands through the
   cards. Same reasoning as the lender strip.

   The band pauses on hover and on keyboard focus. That pause is the only way to
   read a long quote here, and it does not exist on touch — which is why the
   selection is capped at 240 characters in build/templates.js. */
.reviews-mq{position:relative;overflow:hidden;padding:10px 0;margin:0 0 6px;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 6%,#000 94%,transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 6%,#000 94%,transparent 100%);
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-size:100% 100%;mask-size:100% 100%}
.reviews-mq__track{--mq-gap:22px;display:flex;gap:var(--mq-gap);width:max-content;align-items:stretch;
  animation:reviewsSlide var(--mq-dur,120s) linear infinite}
/* display:contents so the two passes do not become flex items themselves */
.reviews-mq__pass{display:contents}
.reviews-mq .review{width:352px;flex:0 0 352px}
/* half the track is one full pass; the extra half-gap lands the loop exactly on
   the seam so there is no jump on repeat */
@keyframes reviewsSlide{from{transform:translateX(0)}to{transform:translateX(calc(-50% - var(--mq-gap) / 2))}}
.reviews-mq:hover .reviews-mq__track,
.reviews-mq:focus-within .reviews-mq__track{animation-play-state:paused}
@media (max-width:620px){
  .reviews-mq .review{width:300px;flex:0 0 300px}
  .reviews-mq__track{--mq-gap:16px}
}
/* the full wall on reviews.html: masonry so cards of very different lengths
   don't leave ragged gaps in a rigid grid */
.reviews--wall{display:block;columns:3;column-gap:24px}
.reviews--wall .review{break-inside:avoid;margin-bottom:24px}
.review{position:relative;background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:30px;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;gap:14px;overflow:hidden}
.review::before{content:"\201C";position:absolute;top:-6px;right:18px;font-family:Georgia,"Times New Roman",serif;font-size:6rem;line-height:1;color:var(--gold-400);opacity:.28;pointer-events:none}
.review__head{display:flex;align-items:center;gap:12px;flex-wrap:wrap;position:relative}
.stars{color:var(--gold-500);font-size:1.15rem;letter-spacing:2px;line-height:1}
/* .68rem is 10.9px — under the point where a phone screen makes uppercase
   with letter-spacing hard work. */
.review__tag{font-family:var(--font-head);font-size:.74rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--blue-600);background:var(--bg-tint);border-radius:999px;padding:.4em .9em}
.review blockquote{font-size:1.02rem;color:var(--ink);line-height:1.6;font-style:italic;flex:1;position:relative}
.review__who{display:flex;align-items:center;gap:13px;margin-top:auto}
.review__ph{flex:none;width:46px;height:46px;border-radius:50%;object-fit:cover;background:var(--bg-tint);
  box-shadow:0 0 0 1px var(--line),0 2px 8px rgba(16,35,66,.14)}
.review__ph--txt{display:grid;place-items:center;box-shadow:none;
  background:linear-gradient(140deg,var(--gold-500),var(--gold-400));color:var(--navy-900);
  font-family:var(--font-head);font-weight:800;font-size:.95rem;letter-spacing:.02em}
.review__id{display:flex;flex-direction:column;gap:2px;min-width:0}
.review__id strong{font-family:var(--font-head);color:var(--ink);line-height:1.25}
.review__src{display:inline-flex;align-items:center;gap:.45em;flex-wrap:wrap;font-size:.83rem;color:var(--muted)}
.fb-mark{width:14px;height:14px;flex:none;fill:#1877f2}
.review__tr{font-size:.72rem;color:var(--blue-600);background:var(--bg-tint);border-radius:5px;padding:.15em .55em;align-self:flex-start}
.reviews__all{text-align:center;margin-top:38px}

/* ---------- Reviews page: summary block ---------- */
.reviews-summary{max-width:760px;margin:0 auto;text-align:center;display:flex;flex-direction:column;align-items:center;gap:22px}
.faces{display:flex;justify-content:center}
.faces img{width:46px;height:46px;border-radius:50%;object-fit:cover;margin-left:-13px;
  border:3px solid var(--bg-soft);background:var(--bg-tint)}
.faces img:first-child{margin-left:0}
.faces__more{width:46px;height:46px;border-radius:50%;margin-left:-13px;display:grid;place-items:center;
  border:3px solid var(--bg-soft);background:linear-gradient(140deg,var(--gold-500),var(--gold-400));
  color:var(--navy-900);font-family:var(--font-head);font-weight:800;font-size:.82rem}
.reviews-summary__stats{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;width:100%}
.reviews-summary__note{font-size:.95rem;color:var(--muted);max-width:60ch}

/* ---------- Proof strip (service pages) ---------- */
.section--flush{padding-top:0}
.proof-strip{display:flex;align-items:center;gap:20px;flex-wrap:wrap;
  background:var(--bg-tint);border:1px solid var(--line);border-radius:var(--radius);padding:20px 26px}
.proof-strip .review__ph{width:52px;height:52px}
.proof-strip__txt{flex:1;min-width:260px;display:flex;flex-direction:column;gap:6px}
.proof-strip__txt q{font-size:1rem;color:var(--ink);font-style:italic}
.proof-strip__who{font-size:.83rem;color:var(--muted)}
.proof-strip__cta{display:inline-flex;align-items:center;gap:.5em;font-family:var(--font-head);font-weight:700;
  font-size:.92rem;color:var(--blue-600);white-space:nowrap}
/* "28 clients recommend us" on one line needs 302px; a 320px phone has
   268px of it after padding. Below 480 the label wraps instead of
   pushing the page sideways. */
/* On a phone the strip stops being a row. Three things — a 52px portrait,
   a quote and a "28 clients recommend us" link — cannot share 342px
   without the quote being crushed to a few characters per line, and the
   260px floor that protects it on a tablet is itself wider than a 320px
   column. Stacking removes the competition instead of arbitrating it. */
@media (max-width:560px){
  .proof-strip{flex-direction:column;align-items:flex-start;gap:14px}
  .proof-strip__txt{min-width:0;width:100%}
  .proof-strip__cta{white-space:normal}
}
.proof-strip__cta svg{width:17px;height:17px;fill:none;stroke:var(--blue-600);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:transform .25s var(--ease)}
.proof-strip__cta:hover svg{transform:translateX(3px)}

/* ---------- Contact ---------- */
.contact{padding:92px 0;background:linear-gradient(160deg,var(--navy-900),var(--navy-800));color:#fff}
.contact__inner{display:grid;grid-template-columns:1fr 1.05fr;gap:56px;align-items:start}
.contact__info h2{color:#fff;font-size:clamp(1.33rem,2.38vw,1.89rem);margin-bottom:.7rem}
.contact__lead{color:#c9d6ec;font-size:1.08rem;margin-bottom:2rem;max-width:32em}
.contact__list{display:grid;gap:20px}
.contact__list li{display:flex;gap:16px;align-items:flex-start}
.contact__ic{flex:none;width:48px;height:48px;border-radius:13px;display:grid;place-items:center;background:rgba(255,255,255,.08)}
.contact__ic svg{width:22px;height:22px;fill:var(--gold-400)}
.contact__list em{display:block;font-style:normal;font-size:.8rem;letter-spacing:.06em;text-transform:uppercase;color:#8fa3c4;margin-bottom:.15rem}
/* The email address is one 27-character token. At 320px it sets the
   min-content width of the whole column, which pushes the grid wider
   than the viewport and gives the page a sideways scroll — so it is
   allowed to break mid-word rather than drag the layout with it. */
.contact__list a{color:#fff;font-family:var(--font-head);font-weight:600;font-size:1.05rem;transition:color .2s;overflow-wrap:anywhere}
.contact__list a:hover{color:var(--gold-400)}
.contact__list span:not(.contact__ic){color:#dbe5f5;font-weight:500;line-height:1.5}

.contact__form-wrap{background:#fff;border-radius:var(--radius-lg);padding:34px;box-shadow:var(--shadow-lg)}
.contact__form{display:grid;gap:16px}
.consent{display:flex;gap:10px;align-items:flex-start;font-size:.86rem;color:var(--body)}
.consent input{margin-top:3px;width:17px;height:17px;accent-color:var(--blue-600);flex:none}
.form-status{font-size:.92rem;padding:.8em 1em;border-radius:10px;text-align:center;font-weight:600}
.form-status.is-ok{background:#e7f6ed;color:#1a7a44}
.form-status.is-err{background:#fdeaea;color:#b3261e}

/* ---------- Footer ---------- */
/* The hairline exists because of the CTA band above it. That band now ends
   on --navy-950, a shade off the footer's own navy, so the two surfaces
   meet with roughly 1.1:1 between them and the join vanishes — the page
   would stop having an ending and simply fade out. One line of the same
   rgba(255,255,255,.09) already used inside the footer draws the seam
   back without touching either colour. */
.footer{background:var(--navy-900);color:#aebdd6;border-top:1px solid rgba(255,255,255,.09)}
/* Five columns now that Specialist has its own. The gap comes down from 40px to
   32px to pay for it: at 40px the three link columns fall under 170px and
   "Development Finance" and "Family Income Benefit" both wrap to two lines. */
.footer__grid{display:grid;grid-template-columns:1.45fr 1fr 1fr 1fr 1.15fr;gap:32px;padding:70px 24px 48px}
.footer__tag{font-size:.95rem;color:#8fa3c4;margin:18px 0;max-width:30em}
/* Footer social icons removed with their markup — the profiles remain in
   the topbar and in JSON-LD sameAs, so nothing is lost, only repeated. */
.footer__col h4{color:#fff;font-size:1.02rem;margin-bottom:18px;font-weight:700}
.footer__col ul{display:grid;gap:11px}
/* The three service columns are <details> so they can collapse on a phone —
   see the 520px block. At every width above that they are open and must not
   read as a control: no disclosure triangle, no pointer, no toggling. */
.footer__col--links > summary{display:block;list-style:none}
.footer__col--links > summary::-webkit-details-marker{display:none}
@media (min-width:521px){.footer__col--links > summary{pointer-events:none}}
.footer__col a{font-size:.92rem;color:#aebdd6;transition:color .2s}
.footer__col a:hover{color:var(--gold-400)}
.footer__contact li{display:flex;gap:11px;align-items:flex-start;font-size:.92rem;line-height:1.5}
.footer__contact li svg{flex:none;width:16px;height:16px;fill:var(--gold-400);margin-top:3px}
/* Three groups, not four equal rows: how to reach us (phone, email), where we
   are (address), when we are open (hours). The address wraps to three lines and
   without a break it runs straight into the opening hours as one grey block.
   Marked on the item that ends a group rather than by position, so adding a
   contact line later cannot silently move the breaks. */
.footer__contact li.is-group-end{margin-bottom:12px}
/* review link in the brand column — needs .footer__col specificity to beat `.footer__col a`.
   The brand column narrows to ~150px in the 620–1024px band, so the label is wrapped in its
   own span and the row is allowed to wrap: the stars drop to their own line instead of the
   text shredding into four. */
/* Option F: four reviewer photos set into the line, then the count.
   The facepile reuses .faces from the reviews page; the overrides below
   re-ring it for the navy ground — the ring must be the surface behind
   it, or the overlaps read as pasted-on instead of cut out — and take it
   from 46px (a centrepiece size) to 34px (an inline one). */
.footer__col .footer__reviews{display:inline-flex;flex-wrap:wrap;align-items:center;gap:8px 14px;margin-top:22px;font-size:.9rem;color:#aebdd6}
.footer__reviews > span:last-child{display:inline-flex;align-items:center;gap:7px;white-space:nowrap}
.footer__reviews strong{color:#fff;font-weight:600}
.footer__col .footer__reviews:hover{color:var(--gold-400)}
.footer__reviews .faces img,.footer__reviews .faces__more{width:34px;height:34px;
  border-width:2px;border-color:var(--navy-900);margin-left:-9px}
.footer__reviews .faces img:first-child{margin-left:0}
.footer__reviews .faces__more{background:rgba(232,168,56,.16);color:var(--gold-400);
  font-size:.72rem;font-weight:700}
.footer__reviews-arw{width:15px;height:15px;flex:none;fill:none;stroke:var(--gold-400);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:transform .25s var(--ease)}
.footer__reviews:hover .footer__reviews-arw{transform:translateX(3px)}
.footer__legal{border-top:1px solid rgba(255,255,255,.09);padding:26px 0}

/* Tier one — the credentials, presented as credentials. Badges and the
   headline claim at full brightness, so a visitor scanning the bottom of
   the page reads "regulated, and here is where to check" as a statement
   rather than as small print they have to decode. */
.footer__creds{display:flex;align-items:center;gap:22px;flex-wrap:wrap;
  padding-bottom:18px;margin-bottom:20px;border-bottom:1px solid rgba(255,255,255,.09)}
.footer__creds-line{flex:1 1 340px;display:grid;gap:3px}
.footer__creds-line strong{font-family:var(--font-head);font-weight:700;font-size:.9rem;
  color:#e3ebf8;letter-spacing:-.01em;line-height:1.35}
.footer__creds-line span{font-size:.78rem;color:#8093b0;line-height:1.6}
/* Specificity, not source order: .footer__legal a and .footer__creds-line a
   both score (0,1,1), so whichever came last would win and a later edit
   moving either block would silently swap the register link's colour. The
   descendant selector settles it at (0,2,1). */
.footer__creds .footer__creds-line a{color:var(--gold-400);text-decoration:none;
  border-bottom:1px solid rgba(242,189,87,.45);transition:color .2s,border-color .2s}
.footer__creds .footer__creds-line a:hover{color:#fff;border-bottom-color:#fff}
/* In flow, not absolutely positioned over the text — that is what let the
   badges sit on top of the authorisation statement in the first place. */
.footer__badges{display:flex;gap:14px;align-items:center}
.footer__badges img{height:42px;width:auto;opacity:.9;transition:opacity .2s}
.footer__badges img:hover{opacity:1}

/* Tier two — the notice. The warning leads and carries the gold rule.

   The wide column goes to the WARNING, not to the prose, which is the
   opposite of the obvious arrangement. Two reasons, both measured at
   1180px. The repossession sentence runs 553px set semibold at .86rem:
   given 588px it lands on one line, given 468px it breaks two words onto
   a second. And the authorisation statement wants ~70 characters a line,
   which at .78rem is 486px — exactly what the narrow column gives it.

   So the columns are sized to the text rather than to its importance,
   and neither needs a max-width propping it up. The earlier arrangement
   had the prose capped at 62ch inside a 608px column, which left 110px
   of dead space at the right edge and made the whole band look like it
   had stopped early. */
.footer__notice{display:grid;grid-template-columns:1fr 1.3fr;gap:38px;align-items:stretch}
/* align-items:stretch, not start: the warning is two lines and the prose
   beside it is five, so a start-aligned callout left a block of empty
   navy under a gold rule that stopped a third of the way down. Stretched,
   the rule runs the full height of the row and the space below the text
   reads as room inside a bordered block rather than as a hole. */
.footer__notice-risk{border-left:2px solid var(--gold-500);padding-left:16px}
/* balance, because this column is now narrower than the sentence: without
   it the wrap leaves one or two words alone on the second line. */
.footer__risk{color:#fff;font-weight:600;font-size:.86rem;line-height:1.6;text-wrap:balance}
.footer__fee{margin-top:.5rem;color:#c3d2e8;font-size:.8rem;line-height:1.6}
/* No max-width: the column is already the right measure, and a cap on top
   of it would only pull the text off the right edge again. */
.footer__notice-prose p{font-size:.78rem;color:#8093b0;line-height:1.65}
.footer__notice-prose p+p{margin-top:.6rem}
/* The link to the FCA register was once the same colour as the text around
   it and carried no underline — a 1.0 contrast ratio against its own
   paragraph, so it was not a link to anyone. */
.footer__legal a{color:#a9bcd8;text-decoration:underline;text-underline-offset:2px;
  text-decoration-thickness:1px;transition:color .2s}
.footer__legal a:hover{color:#fff}
.footer__bottom{border-top:1px solid rgba(255,255,255,.09);padding:20px 0}
.footer__bottom-inner{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}
.footer__bottom p{font-size:.85rem;color:#8093b0}
.footer__credit a{color:var(--gold-400);font-weight:600;transition:color .2s}
.footer__credit a:hover{color:var(--gold-500);text-decoration:underline}

/* ---------- Back to top ---------- */
.to-top{position:fixed;right:22px;bottom:22px;width:48px;height:48px;border-radius:50%;display:grid;place-items:center;
  background:var(--blue-600);box-shadow:var(--shadow-md);opacity:0;visibility:hidden;transform:translateY(12px);transition:opacity .3s,transform .3s,background .2s;z-index:90}
.to-top.is-visible{opacity:1;visibility:visible;transform:translateY(0)}
.to-top:hover{background:var(--gold-500)}
.to-top svg{width:22px;height:22px;fill:#fff}

/* ---------- Footer brand logo ---------- */
.footer__brand{display:inline-block;margin-bottom:6px}
.footer__brand img{height:78px;width:auto}

/* ---------- Sub-hero (inner pages) ---------- */
/* No photograph on inner pages: the ground is the same navy-on-navy
   with a blue bloom that the CTA band wears, so the two dark bands at
   the top and bottom of a page are recognisably the same surface.

   Twenty-five per-page background rules used to live here, one for each
   .subhero--<slug>. The variant class is still emitted — it is the hook
   if a page ever wants its own treatment — but nothing hangs off it now. */
.subhero{position:relative;color:#fff;overflow:hidden;
  background:radial-gradient(62% 150% at 16% 24%,rgba(26,79,156,.5),transparent 70%),
             linear-gradient(120deg,var(--navy-800),var(--navy-950))}
/* soft curved bottom edge into the page */
.subhero::after{content:"";position:absolute;left:-6%;right:-6%;bottom:-1px;height:32px;z-index:2;
  background:#fff;border-radius:50% 50% 0 0 / 100% 100% 0 0}
.subhero__inner{position:relative;z-index:1;padding:54px 24px 60px;max-width:820px}
/* The text shadows went with the photograph. --on-photo stacks four of
   them to punch type through a picture; over a flat navy it only smears
   the edges of letters that already have 12:1 behind them. */
.subhero h1{color:#fff;font-size:clamp(1.3rem,2.6vw,1.95rem);margin-bottom:.6rem}
.subhero p{color:#e7eefb;font-size:1.12rem;max-width:44em}
.crumbs{display:flex;flex-wrap:wrap;align-items:center;gap:.5em;font-size:.85rem;
  color:#b9c8e0;margin-bottom:1.1rem}
.crumbs a{color:#d5e1f2;transition:color .2s}
.crumbs a:hover{color:var(--gold-400)}
.crumbs span[aria-hidden]{opacity:.5}
.crumbs .is-current{color:#fff;font-weight:600}

/* ---------- Service detail ---------- */
.detail{padding:76px 0}
.detail__grid{display:grid;grid-template-columns:1fr 350px;gap:48px;align-items:start}
.detail__intro p{font-size:1.1rem;color:var(--body);margin-bottom:1.1rem}
.detail__intro p:first-child{font-size:1.18rem;color:var(--ink)}
.detail__h2{font-size:1.6rem;margin:2.4rem 0 1.2rem}
.detail__main > .detail__intro + .detail__h2{margin-top:2.6rem}

.features{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.feature{display:flex;gap:14px;background:var(--bg-soft);border:1px solid var(--line);border-radius:var(--radius);padding:20px}
.feature__check{flex:none;width:34px;height:34px;border-radius:9px;background:var(--bg-tint);display:grid;place-items:center}
.feature__check svg{width:18px;height:18px;fill:none;stroke:var(--blue-600);stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.feature h3{font-size:1.05rem;margin-bottom:.25rem}
.feature p{font-size:.92rem}

.foryou{background:linear-gradient(160deg,var(--bg-tint),var(--bg-soft));border:1px solid var(--line);border-radius:var(--radius-lg);padding:30px 32px;margin-top:2.4rem}
.foryou .detail__h2{margin-top:0}
.foryou > p{margin-bottom:1rem;color:var(--body)}
.ticklist{display:grid;gap:12px}
.ticklist li{position:relative;padding-left:36px;font-size:1rem;color:var(--ink)}
.ticklist li::before{content:"";position:absolute;left:0;top:1px;width:23px;height:23px;border-radius:50%;
  background:var(--blue-600) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/13px no-repeat}

/* FAQ accordion */
.faqs{display:grid;gap:12px}
.faq{border:1px solid var(--line);border-radius:var(--radius-sm);background:#fff;overflow:hidden}
.faq summary{list-style:none;cursor:pointer;padding:18px 22px;font-family:var(--font-head);font-weight:700;color:var(--ink);font-size:1.02rem;display:flex;align-items:center;justify-content:space-between;gap:14px}
.faq summary::-webkit-details-marker{display:none}
.faq__icon{width:20px;height:20px;flex:none;fill:none;stroke:var(--blue-600);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;transition:transform .3s}
.faq[open] .faq__icon{transform:rotate(180deg)}
.faq[open] summary{color:var(--blue-600)}
.faq__body{padding:0 22px 20px}
.faq__body p{font-size:.98rem;color:var(--body)}

/* Sidebar advice card */
.detail__aside{position:sticky;top:104px}
.advice-card{background:linear-gradient(160deg,var(--navy-800),var(--navy-900));color:#fff;border-radius:var(--radius-lg);padding:30px;box-shadow:var(--shadow-lg)}
.advice-card__icon{width:52px;height:52px;border-radius:14px;background:rgba(255,255,255,.1);display:grid;place-items:center;margin-bottom:16px}
.advice-card__icon svg{width:26px;height:26px;fill:var(--gold-400)}
.advice-card h3{color:#fff;font-size:1.3rem;margin-bottom:.4rem}
.advice-card > p{color:#c9d6ec;font-size:.95rem;margin-bottom:1.4rem}
.advice-card .btn{margin-bottom:10px}
.advice-card .btn--ghost{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.2);color:#fff}
.advice-card .btn--ghost svg{fill:var(--gold-400)}
.advice-card .btn--ghost:hover{border-color:var(--gold-400);background:rgba(255,255,255,.12)}
.advice-card__meta{margin-top:16px;padding-top:16px;border-top:1px solid rgba(255,255,255,.12);display:grid;gap:10px}
.advice-card__meta span{display:flex;align-items:center;gap:10px;font-size:.9rem;color:#c9d6ec}
.advice-card__meta svg{width:16px;height:16px;fill:var(--gold-400);flex:none}
/* info@homewaymortgages.co.uk is one 27-character token with nowhere to
   break. At 320px it set the min-content width of the whole detail grid
   and gave every service page a sideways scroll. */
.advice-card__meta a{color:#c9d6ec;transition:color .2s;overflow-wrap:anywhere}
.advice-card__meta a:hover{color:#fff}

.cards--3{grid-template-columns:repeat(3,1fr)}

/* ---------- CTA band ---------- */
/* Two near-identical navies lit by a blue bloom behind the heading, rather
   than a left-to-right sweep out of the action blue.

   The old ground opened on --blue-600, the same hue that fills every
   primary button on the site. Spread across a third of a band, a colour
   the eye has been taught means "press this" sits on a surface that is
   not pressable — bright, and slightly misleading with it.

   The bloom is sized in percentages, not the pixels it was mocked up in,
   so it stays proportional when the band grows tall on a phone. Anything
   fixed would cover a 300px-wide band entirely and turn the light into a
   flat wash. */
.cta-band{color:#fff;
  background:radial-gradient(62% 170% at 16% 22%,rgba(26,79,156,.5),transparent 70%),
             linear-gradient(120deg,var(--navy-800),var(--navy-950))}
.cta-band__inner{display:flex;align-items:center;justify-content:space-between;gap:32px;padding:52px 24px;flex-wrap:wrap}
.cta-band h2{color:#fff;font-size:clamp(1.12rem,2.1vw,1.54rem);margin-bottom:.3rem}
.cta-band p{color:#d6e2f6;font-size:1.05rem;max-width:34em}
/* Copy takes the slack, the buttons keep their natural width. Without
   flex:0 0 auto on the actions the two children share the space evenly,
   the buttons get more than they need, and the copy hits its wrap point
   early — the bar then breaks into two rows while there is still room
   for one. */
.cta-band__copy{flex:1 1 0;min-width:0}
/* wrap so the two buttons stack under each other on a narrow phone
   instead of running past the edge of their own box */
.cta-band__actions{display:flex;gap:14px;flex:0 0 auto;flex-wrap:wrap}
.cta-band .btn--primary{box-shadow:0 10px 24px rgba(0,0,0,.2)}

/* ---------- Values (about) ---------- */
.values{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
/* align-content:start for the same reason as .benefit: the cards stretch to the
   tallest sibling and the default hands the leftover height to the auto rows,
   so the card with the shortest text sits its centred icon and title several
   pixels below the others. Here it showed on "On your side" against its
   neighbours. Extra space now collects at the bottom, where it is invisible. */
.value{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:26px 24px;box-shadow:var(--shadow-sm);transition:transform .3s var(--ease),box-shadow .3s;
  display:grid;grid-template-columns:auto 1fr;column-gap:14px;align-content:start}
.value:hover{transform:translateY(-6px);box-shadow:var(--shadow-md)}
.value__icon{grid-column:1;grid-row:1;align-self:center;width:50px;height:50px;border-radius:13px;background:var(--bg-tint);display:grid;place-items:center}
.value__icon svg{width:26px;height:26px;fill:none;stroke:var(--blue-600);stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.value h3{grid-column:2;grid-row:1;align-self:center;font-size:1.1rem;margin:0}
.value p{grid-column:1 / -1;grid-row:2;font-size:.92rem;margin-top:14px}

/* ---------- Full-bleed photo card ----------
   .value--photo rides along on every rule here rather than getting a copy of
   them. The values on About and the services on the hub pages are the same
   component wearing two class names, and two copies of a gradient this fiddly
   would drift apart the first time either was touched. That is also why both
   use .card__ph / .card__b inside.

   Placed after BOTH .card and .value on purpose. It first sat up with the card
   rules, where `.value{display:grid}` further down the file quietly won on
   equal specificity — the grid stayed on, the body landed in row two, and the
   copy printed across the top of the photo instead of the bottom. Same
   specificity means source order decides, so this block has to come last. */
.card--photo,.value--photo,.step{padding:0;border:0;overflow:hidden;aspect-ratio:3/4;
  display:flex;align-items:flex-end;box-shadow:var(--shadow-md);
  border-radius:var(--radius);background:#fff;position:relative;
  transition:transform .3s var(--ease),box-shadow .3s}
.card--photo:hover,.value--photo:hover,.step:hover{box-shadow:var(--shadow-lg);transform:translateY(-6px)}
/* the base card's gold top hairline has nothing to sit against here */
.card--photo::before{display:none}
.card__ph{position:absolute;inset:0;display:block;z-index:0}
.card__ph img{width:100%;height:100%;object-fit:cover;transition:transform .6s var(--ease)}
.card--photo:hover .card__ph img,.value--photo:hover .card__ph img,.step:hover .card__ph img{transform:scale(1.06)}
.card--photo::after,.value--photo::after,.step::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(8,24,51,.04) 30%,rgba(8,24,51,.72) 68%,rgba(6,16,38,.94) 100%)}
.card__b{position:relative;z-index:2;padding:22px;display:flex;flex-direction:column;width:100%}
.card--photo h3,.value--photo h3,.step h3{color:#fff;font-size:1.1rem;margin:0 0 .4rem;text-shadow:0 1px 3px rgba(6,16,38,.6)}
.card--photo p,.value--photo p,.step p{color:#d3ddee;font-size:.88rem;margin:0;text-shadow:0 1px 3px rgba(6,16,38,.6)}
.card--photo .card__link{color:var(--gold-400);margin-top:12px;font-size:.86rem}
.card--photo:hover .card__link{color:#fff}

/* ---------- About intro ---------- */
.about__intro{display:grid;grid-template-columns:1.2fr .8fr;gap:52px;align-items:center}
.about__text h2{font-size:clamp(1.26rem,2.24vw,1.75rem);margin-bottom:1rem}
.about__text p{font-size:1.05rem;margin-bottom:1rem}
.about__actions{display:flex;align-items:center;gap:22px;flex-wrap:wrap;margin-top:1.6rem}
.about__stats{display:grid;grid-template-columns:1fr 1fr;gap:18px}

/* ---------- Contact page ---------- */
.contact-page{display:grid;grid-template-columns:.9fr 1.1fr;gap:52px;align-items:start}
.contact__info--light h2{color:var(--ink);font-size:clamp(1.19rem,2.1vw,1.61rem);margin-bottom:.6rem}
.contact__info--light .contact__lead{color:var(--muted)}
.contact__info--light .contact__ic{background:var(--bg-tint)}
.contact__info--light .contact__ic svg{fill:var(--blue-600)}
.contact__info--light .contact__list em{color:var(--muted)}
.contact__info--light .contact__list a{color:var(--ink)}
.contact__info--light .contact__list a:hover{color:var(--blue-600)}
.contact__info--light .contact__list span:not(.contact__ic){color:var(--body)}
.contact__social{display:flex;gap:10px;margin-top:26px}
.contact__social a{width:42px;height:42px;border-radius:11px;display:grid;place-items:center;background:var(--bg-tint);transition:background .2s,transform .2s}
.contact__social a:hover{background:var(--blue-600);transform:translateY(-3px)}
.contact__social svg{width:19px;height:19px;fill:var(--blue-600);transition:fill .2s}
.contact__social a:hover svg{fill:#fff}
.page-contact .contact__form-wrap{border:1px solid var(--line)}

/* ---------- Map ---------- */
.map-band{height:420px;background:var(--bg-soft)}
.map-band iframe{width:100%;height:100%;border:0;display:block;filter:grayscale(.2)}

/* ---------- Calculators ---------- */
.calc-tabs{display:flex;gap:6px;background:var(--bg-soft);border:1px solid var(--line);border-radius:999px;padding:6px;max-width:560px;margin:0 auto 36px}
.calc-tab{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:.5em;border:none;background:transparent;border-radius:999px;
  font-family:var(--font-head);font-weight:700;font-size:.95rem;color:var(--body);padding:.75em .6em;transition:background .25s,color .25s,box-shadow .25s}
.calc-tab svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.calc-tab:hover{color:var(--blue-600)}
.calc-tab.is-active{background:#fff;color:var(--blue-600);box-shadow:var(--shadow-sm)}
.calc-tab.is-active svg{stroke:var(--blue-600)}

.calc-panel{display:none}
.calc-panel.is-active{display:block;animation:fadeUp .4s var(--ease)}
@keyframes fadeUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

.calc{display:grid;grid-template-columns:1fr .85fr;gap:0;border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-md);background:#fff}
.calc__inputs{padding:34px 34px 38px}
.calc__title{font-size:1.5rem;margin-bottom:.4rem}
.calc__intro{font-size:.95rem;color:var(--muted);margin-bottom:1.6rem}
.calc__inputs .field{margin-bottom:16px}
.calc__output{background:linear-gradient(160deg,var(--navy-800),var(--navy-900));color:#fff;padding:34px;display:flex;flex-direction:column;justify-content:center}
.calc-result{text-align:center;margin-bottom:22px}
.calc-result__label{display:block;font-size:.85rem;letter-spacing:.05em;text-transform:uppercase;color:#8fa3c4;margin-bottom:.5rem}
.calc-result__value{display:block;font-family:var(--font-head);font-weight:800;font-size:clamp(2.2rem,4.5vw,3rem);color:var(--gold-400);line-height:1.05;letter-spacing:-.02em}
.calc-stats{display:grid;gap:1px;background:rgba(255,255,255,.12);border-radius:12px;overflow:hidden;margin-bottom:22px}
.calc-stats li{display:flex;align-items:center;justify-content:space-between;gap:12px;background:rgba(255,255,255,.04);padding:14px 18px}
.calc-stats span{font-size:.9rem;color:#c9d6ec}
.calc-stats strong{font-family:var(--font-head);font-weight:700;color:#fff;font-size:1.05rem}
.calc__output .btn--primary{box-shadow:0 10px 24px rgba(0,0,0,.25)}

.calc-disclaimer{display:flex;gap:16px;align-items:flex-start;max-width:860px;margin:32px auto 0;padding:20px 24px;
  background:var(--bg-soft);border:1px solid var(--line);border-radius:var(--radius);font-size:.88rem;color:var(--muted);line-height:1.7}
.calc-disclaimer svg{flex:none;width:22px;height:22px;padding:9px;box-sizing:content-box;border-radius:50%;background:var(--bg-tint);
  fill:none;stroke:var(--blue-600);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.calc-disclaimer span{flex:1}
.calc-disclaimer a{color:var(--blue-600);font-weight:600;text-decoration:underline;white-space:nowrap}

/* ---------- Accessibility: skip link + focus ---------- */
.skip-link{position:fixed;top:-60px;left:12px;z-index:200;background:var(--gold-500);color:var(--navy-900);
  font-family:var(--font-head);font-weight:700;padding:.7em 1.2em;border-radius:10px;transition:top .2s}
.skip-link:focus{top:12px}
:focus-visible{outline:3px solid var(--gold-500);outline-offset:2px;border-radius:4px}
.hero :focus-visible,.contact :focus-visible,.header :focus-visible{outline-color:var(--gold-400)}

/* Honeypot (spam trap) — kept out of view for humans */
.hp-field{position:absolute!important;left:-9999px!important;width:1px;height:1px;opacity:0;pointer-events:none}

/* ---------- Recommend badge ----------
   Facebook has no star scores, so this states the checkable fact
   ("100% recommend") rather than an invented rating out of five. */
.recommend-badge{display:inline-flex;align-items:center;gap:10px;margin-top:18px;padding:.6em 1.2em;
  background:#fff;border:1px solid var(--line);border-radius:999px;box-shadow:var(--shadow-sm);font-size:.95rem;flex-wrap:wrap;justify-content:center}
.recommend-badge .fb-mark{width:17px;height:17px}
.recommend-badge .stars{font-size:1.02rem;letter-spacing:1px}
.recommend-badge strong{font-family:var(--font-head);color:var(--ink)}
.recommend-badge span{color:var(--muted)}

/* ---------- Cookie consent ---------- */
.cookie{position:fixed;left:12px;right:12px;bottom:12px;z-index:120;max-width:560px;margin:0 auto;
  background:#fff;border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow-lg);
  animation:fadeUp .4s var(--ease)}
.cookie[hidden]{display:none}
.cookie__inner{padding:20px 22px}
.cookie__inner p{font-size:.88rem;color:var(--body);margin-bottom:14px}
.cookie__actions{display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap}

/* ---------- Reveal animation ---------- */
[data-reveal]{opacity:0;transform:translateY(26px);transition:opacity .7s var(--ease),transform .7s var(--ease)}
[data-reveal].is-in{opacity:1;transform:none}

/* ---------- WhatsApp float ---------- */
/* The navy disc is baked into call-center-icon.png, so the button itself
   carries no background — only the shadow that lifts it off the page. */
.wa-float{position:fixed;left:22px;bottom:22px;width:52px;height:52px;border-radius:50%;display:block;
  box-shadow:0 8px 22px rgba(8,24,51,.42);z-index:90;transition:transform .2s,box-shadow .2s}
.wa-float:hover{transform:translateY(-3px) scale(1.05);box-shadow:0 12px 28px rgba(8,24,51,.52)}
.wa-float img{width:100%;height:100%;display:block;border-radius:50%}

/* ---------- Footer legal links ---------- */
.footer__legal-links{display:flex;gap:18px;flex-wrap:wrap}
.footer__legal-links a{font-size:.85rem;color:#8093b0;transition:color .2s}
.footer__legal-links a:hover{color:var(--gold-400)}

/* ---------- Team section ---------- */
.team{display:grid;grid-template-columns:.85fr 1.15fr;gap:48px;align-items:center}
.team__card{position:relative;border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-lg);max-width:420px;width:100%;
  background:linear-gradient(160deg,var(--navy-800),var(--navy-700));color:#c6d3e8;padding:38px 32px 70px;display:flex;flex-direction:column;align-items:flex-start;gap:24px}
.team__card::before{content:"";position:absolute;top:-70px;right:-70px;width:240px;height:240px;border-radius:50%;
  background:radial-gradient(circle,rgba(242,189,87,.20),transparent 70%);pointer-events:none}
.team__card>img{width:170px;height:auto;display:block}
.team__partner{display:flex;flex-direction:column;gap:4px;padding-top:22px;border-top:1px solid rgba(255,255,255,.14);width:100%}
.team__partner span{font-size:.76rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:#8fa3c4}
.team__partner strong{font-family:var(--font-head);font-weight:700;font-size:1.32rem;line-height:1.25;color:#fff}
.team__partner em{font-style:normal;font-size:.92rem;color:#c6d3e8}
.team__points{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:12px}
.team__points li{display:flex;align-items:flex-start;gap:10px;font-size:.95rem;line-height:1.45;color:#dbe4f3}
.team__points svg{width:18px;height:18px;flex:none;margin-top:2px;fill:none;stroke:var(--gold-400);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.team__badge{position:absolute;left:16px;bottom:16px;display:inline-flex;align-items:center;gap:.5em;
  background:rgba(9,24,52,.9);color:#fff;font-family:var(--font-head);font-weight:700;font-size:.78rem;padding:.55em 1em;border-radius:999px;backdrop-filter:blur(6px);border:1px solid rgba(255,255,255,.12)}
/* flex:none — the badge is inline-flex, so at 320px the label took the
   space first and squeezed this 24×24 shield into a 9×15 box. */
.team__badge svg{flex:none;width:15px;height:15px;fill:none;stroke:var(--gold-400);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.team__body h2{font-size:clamp(1.19rem,2.1vw,1.68rem);margin-bottom:.7rem}
.team__body p.team__name{font-family:"Dancing Script",cursive;font-weight:600;font-size:2.7rem;line-height:1;color:var(--navy-800);margin-bottom:.35rem}
.team__role{font-family:var(--font-head);font-weight:700;color:var(--blue-600);margin-bottom:1rem}
.team__body p{font-size:1.05rem;margin-bottom:1rem}
.team__actions{display:flex;align-items:center;gap:22px;flex-wrap:wrap;margin-top:1.4rem}

/* ---------- Multi-step wizard ---------- */
.wizard__progress{display:flex;align-items:center;gap:14px;margin-bottom:22px}
.wizard__bar{flex:1;height:7px;border-radius:999px;background:var(--bg-tint);overflow:hidden}
.wizard__bar i{display:block;height:100%;width:33%;border-radius:999px;background:linear-gradient(90deg,var(--gold-500),var(--gold-400));transition:width .35s var(--ease)}
.wizard__count{font-size:.82rem;color:var(--muted);font-weight:600;white-space:nowrap}
.wizard__count b{color:var(--ink)}
.wizard__step{display:none;border:0;padding:0;margin:0;min-inline-size:0;animation:fadeUp .35s var(--ease)}
.wizard__step.is-active{display:block}
.wizard__q{font-family:var(--font-head);font-weight:700;font-size:1.2rem;color:var(--ink);margin-bottom:16px;padding:0}
.wizard__nav{display:flex;justify-content:space-between;gap:12px;margin-top:20px}
.wizard__nav .btn{min-width:120px}

.wiz-cards{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.wiz-card{position:relative;display:block;padding:18px 16px 16px;border:1.5px solid var(--line);border-radius:var(--radius);cursor:pointer;transition:border-color .2s,background .2s,transform .2s;background:var(--bg-soft)}
.wiz-card:hover{border-color:var(--blue-400);transform:translateY(-2px)}
.wiz-card input{position:absolute;opacity:0;inset:0;cursor:pointer}
.wiz-card__ic{display:grid;place-items:center;width:40px;height:40px;border-radius:11px;background:#fff;border:1px solid var(--line);margin-bottom:10px}
.wiz-card__ic svg{width:22px;height:22px;fill:none;stroke:var(--blue-600);stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.wiz-card__t{display:block;font-family:var(--font-head);font-weight:700;color:var(--ink);font-size:.98rem}
.wiz-card__d{display:block;font-size:.82rem;color:var(--muted);margin-top:.15rem}
.wiz-card:has(input:checked){border-color:var(--blue-500);background:var(--bg-tint);box-shadow:0 0 0 3px rgba(36,105,207,.12)}
.wiz-card:has(input:checked) .wiz-card__ic{background:var(--blue-600);border-color:var(--blue-600)}
.wiz-card:has(input:checked) .wiz-card__ic svg{stroke:#fff}
.wiz-card input:focus-visible{outline:none}
.wiz-card:has(input:focus-visible){outline:2px solid var(--blue-500);outline-offset:2px}

/* ---------- Form furniture shared by both enquiry pages ---------- */
.form-title{font-size:clamp(1.19rem,2.1vw,1.55rem);margin-bottom:.35rem}
.form-sub{color:var(--muted);font-size:.95rem;margin-bottom:20px}
/* The reassurance under the button, not above it: it answers the question
   the reader has while their finger is over "Send", which is the only
   moment it is worth anything. */
.form-note{font-size:.82rem;color:var(--muted);line-height:1.55;margin-top:2px}
.field--gap{margin-top:18px}
.field__hint{font-size:.8rem;color:var(--muted);line-height:1.5}

/* Radio pills — one line each, wrapping. Used for the time slot, where
   four options need to be scannable without eating the height four
   stacked cards would. The input stays in the DOM (never display:none)
   so it keeps its place in the tab order and its own focus ring. */
.pick{border:0;padding:0;margin:18px 0 0;min-inline-size:0}
.pick legend{font-family:var(--font-head);font-weight:600;font-size:.85rem;color:var(--ink);padding:0;margin-bottom:.5rem}
.pill-set{display:flex;flex-wrap:wrap;gap:9px}
.pill{position:relative;display:inline-flex;align-items:center;padding:.62em 1.05em;border:1.5px solid var(--line);
  border-radius:999px;background:var(--bg-soft);cursor:pointer;font-size:.88rem;font-weight:600;color:var(--body);
  transition:border-color .2s,background .2s,color .2s}
.pill:hover{border-color:var(--blue-400)}
.pill input{position:absolute;opacity:0;inset:0;cursor:pointer;border-radius:999px}
.pill:has(input:checked){border-color:var(--blue-500);background:var(--bg-tint);color:var(--ink);box-shadow:0 0 0 3px rgba(36,105,207,.12)}
.pill:has(input:focus-visible){outline:2px solid var(--blue-500);outline-offset:2px}

/* ---------- Contact page: left column ----------
   Only this column stretches to the row height — `align-self`, not
   `align-items` on the grid, because stretching both would pull the
   white form card down to match and leave a pool of empty white under
   the send button. The card keeps its natural height; the column beside
   it grows to meet it, and its last element is pinned to the bottom so
   the two columns finish on the same line. */
.contact__info--light{align-self:stretch;display:flex;flex-direction:column}

/* ---------- "What happens after you send" ----------
   Three sequential facts, so an <ol> with the count showing: the numbers
   say "then this, then this", which is information the reader uses
   rather than ornament.

   The medallion is centred on the FIRST line of a step, not on the whole
   step, so a two-line item does not leave its number floating in the
   middle. The offset is half the difference between the circle and one
   line box, and both halves of that sum are computed from the same two
   custom properties the text itself uses — change the type and the
   number follows. */
.next-steps{--step-fs:.88rem;--step-lh:1.55;--step-medal:26px;
  margin-top:18px;padding:14px 18px 13px;background:var(--bg);
  border:1px solid var(--line);border-radius:var(--radius)}
.next-steps__t{font-family:var(--font-head);font-weight:700;font-size:.98rem;
  color:var(--ink);margin-bottom:10px}
.next-steps ol{margin:0;padding:0;list-style:none;display:grid;gap:11px;counter-reset:step}
.next-steps li{display:grid;grid-template-columns:var(--step-medal) 1fr;gap:12px;
  align-items:start;font-size:var(--step-fs);line-height:var(--step-lh);counter-increment:step}
/* width and height only — never alongside aspect-ratio, which would win
   and turn the circle into an ellipse. */
.next-steps li::before{content:counter(step);
  width:var(--step-medal);height:var(--step-medal);border-radius:50%;
  /* --step-fs, not 1em: inside ::before, 1em is the medallion's own .78rem,
     so the sum silently measured the wrong line and sat 1.2px high. The
     token is in rem, which makes it independent of whatever font-size this
     pseudo-element carries. */
  margin-top:calc((var(--step-fs) * var(--step-lh) - var(--step-medal)) / 2);
  display:grid;place-items:center;
  background:var(--navy-900);color:var(--gold-400);
  font-family:var(--font-head);font-weight:700;font-size:.78rem;font-variant-numeric:tabular-nums}
.next-steps b{color:var(--ink);font-weight:600}

/* ---------- Contact page: cross-link to the booking page ----------
   Someone who wanted a slot in the diary and landed on the message form
   should find the way over without scrolling back to the menu.

   margin-top:auto rather than a fixed margin: it takes whatever slack is
   left in the stretched column, so this box lands on the bottom edge of
   the form card beside it however the block above reflows. */
.contact__book{display:flex;align-items:center;gap:14px;margin-top:auto;padding:16px 18px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--bg-soft);
  transition:border-color .2s,background .2s,transform .2s}
.contact__book:hover{border-color:var(--blue-400);background:var(--bg-tint);transform:translateY(-2px)}
.contact__book-ic{flex:none;display:grid;place-items:center;width:44px;height:44px;border-radius:12px;background:var(--navy-900)}
.contact__book-ic svg{width:21px;height:21px;fill:none;stroke:var(--gold-400);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.contact__book span:not(.contact__book-ic){font-size:.88rem;color:var(--body);line-height:1.5}
.contact__book strong{display:block;font-family:var(--font-head);font-size:1rem;color:var(--ink)}
.contact__book-arw{flex:none;width:20px;height:20px;fill:none;stroke:var(--blue-600);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-left:auto}

/* ---------- Booking page ----------
   Form first in the source and on the left, aside second: the page has
   one job and the reader should meet the first question, not the
   preamble. The aside is sticky on desktop so the three reassurances
   stay beside step three, where the name and number get asked for. */
.booking-page{display:grid;grid-template-columns:1.15fr .85fr;gap:44px;align-items:start}
.booking__form-wrap{background:#fff;border-radius:var(--radius-lg);padding:34px;box-shadow:var(--shadow-lg);border:1px solid var(--line)}
.booking-aside{display:grid;gap:20px;position:sticky;top:104px}
.booking-aside__card{background:var(--bg-soft);border:1px solid var(--line);border-radius:var(--radius);padding:26px 24px}
.booking-aside__card h2{font-size:1.1rem;margin-bottom:1rem}
.reassure{display:grid;gap:16px}
.reassure li{display:flex;gap:13px;align-items:flex-start}
.reassure__ic{flex:none;display:grid;place-items:center;width:30px;height:30px;border-radius:9px;background:#fff;border:1px solid var(--line)}
.reassure__ic svg{width:17px;height:17px;fill:none;stroke:var(--blue-600);stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.reassure strong{display:block;font-family:var(--font-head);font-size:.97rem;color:var(--ink);margin-bottom:.1rem}
.reassure span:not(.reassure__ic){font-size:.87rem;color:var(--body);line-height:1.55}
.booking-aside__call{background:linear-gradient(160deg,var(--navy-900),var(--navy-800));border-radius:var(--radius);padding:26px 24px;color:#fff}
.booking-aside__lead{font-family:var(--font-head);font-weight:700;font-size:1.05rem;margin-bottom:.9rem}
.booking-aside__hours{display:flex;align-items:center;gap:8px;font-size:.85rem;color:#c9d6ec;margin-top:14px}
.booking-aside__hours svg{flex:none;width:16px;height:16px;fill:var(--gold-400)}
.booking-aside__alt{font-size:.85rem;color:#c9d6ec;line-height:1.55;margin-top:16px;padding-top:16px;border-top:1px solid rgba(255,255,255,.14)}
.booking-aside__alt a{color:#fff;font-weight:600;text-decoration:underline;text-underline-offset:3px}
.booking-aside__alt a:hover{color:var(--gold-400)}

/* ---------- Amortisation chart (calculator) ---------- */
.amort{margin:6px 0 18px}
.amort figcaption{font-size:.8rem;color:#8fa3c4;margin-bottom:6px}
.amort svg{width:100%;height:80px;display:block}
.calc__cta-row{display:flex;gap:10px;flex-wrap:wrap}
/* min-width has to clear the longest label, not a guessed 150px — .btn--primary
   is overflow:hidden, so without it the button shrinks past its text and clips */
.calc__cta-row .btn{flex:1 1 auto;min-width:fit-content}
.calc__output .btn--ghost{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.22);color:#fff}
.calc__output .btn--ghost svg{fill:var(--gold-400)}
.calc__output .btn--ghost:hover{border-color:var(--gold-400);background:rgba(255,255,255,.14)}

/* ---------- Prose (legal pages) ---------- */
.prose{max-width:760px;margin:0 auto}
.prose h2{font-size:1.4rem;margin:2rem 0 .7rem}
.prose h2:first-of-type{margin-top:0}
.prose p{margin-bottom:1rem;color:var(--body)}
.prose ul{margin:0 0 1rem;padding-left:1.2rem;list-style:disc;color:var(--body)}
.prose li{margin-bottom:.5rem}
.prose a{color:var(--blue-600);text-decoration:underline;font-weight:600}
.prose__note{display:flex;gap:12px;align-items:flex-start;background:var(--bg-soft);border:1px solid var(--line);border-radius:var(--radius);padding:16px 20px;font-size:.9rem;color:var(--muted)}
.prose__note svg{flex:none;width:20px;height:20px;fill:none;stroke:var(--gold-500);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;margin-top:1px}
.prose__meta{font-size:.85rem;color:var(--muted);margin:14px 0 1.6rem}
/* Cookie table. The scroll wrapper is the standard rule for wide content:
   a four-column table at 320px must scroll inside its own box, never push
   the page sideways. */
.prose .table-scroll{overflow-x:auto;margin-bottom:1rem}
.prose table{width:100%;min-width:560px;border-collapse:collapse;font-size:.9rem}
.prose th,.prose td{border:1px solid var(--line);padding:9px 12px;text-align:left;vertical-align:top;color:var(--body)}
.prose th{background:var(--bg-soft);font-family:var(--font-head);font-size:.82rem;color:var(--ink)}
.prose td code{font-family:ui-monospace,Consolas,monospace;font-size:.85em;color:var(--ink)}

/* ---------- 404 ---------- */
.notfound__actions{display:flex;gap:14px;justify-content:center;flex-wrap:wrap}

/* One sentence per span. An inline-block cannot be split across lines, so when
   a two-sentence line no longer fits, the second sentence moves down whole
   instead of leaving its first word behind on the line above. Used on the
   footer legal lines; apply it anywhere a short multi-sentence string wraps. */
.sn{display:inline-block}

/* ---------- Accessibility: visible focus ---------- */
:focus-visible{outline:2px solid var(--blue-500);outline-offset:2px;border-radius:4px}
.btn:focus-visible{outline-offset:3px}

/* =========================================================
   Responsive
   ========================================================= */
@media (max-width:1080px){
  .cards,.steps{grid-template-columns:repeat(2,1fr)}
  .cards--3{grid-template-columns:repeat(3,1fr)}
  .benefits__grid{grid-template-columns:repeat(2,1fr)}
  .reviews{grid-template-columns:1fr}
  .reviews--wall{columns:2}
  .hero__inner{padding:84px 24px 92px}
  .why__inner{grid-template-columns:1fr;gap:40px}
  /* copy and checklist stop sharing a row well before the figures need to fold */
  .why__top{grid-template-columns:1fr;gap:34px}
  .why__top .checklist{margin-bottom:0}
  /* four across leaves ~230px a card here, and "Point of contact, start to
     finish" needs a second line at that width — two across keeps every label
     on one line, which is the reason the figures moved down here at all */
  .why .why__stats{grid-template-columns:1fr 1fr}
  .contact__inner{grid-template-columns:1fr;gap:40px}
  .values{grid-template-columns:repeat(2,1fr)}
  .detail__grid{grid-template-columns:1fr;gap:36px}
  .detail__aside{position:static;max-width:420px}
  .about__intro{grid-template-columns:1fr;gap:36px}
  .contact-page{grid-template-columns:1fr;gap:36px}
  /* The aside carries reassurance, not instructions — once it is under
     the form it has already been read past, so it stops being sticky. */
  .booking-page{grid-template-columns:1fr;gap:32px}
  .booking-aside{position:static}
  .team{grid-template-columns:1fr;gap:28px}
  .team__card{max-width:420px;margin:0 auto}
}

@media (max-width:860px){
  /* The blur has to go before the drawer can work at all. backdrop-filter makes
     .header a containing block for its position:fixed descendants, and the
     drawer lives inside the header: `inset:0` then resolved against an 81px
     bar instead of the viewport, so the menu opened as a white slab across the
     top of the page with no way to close it. A solid bar looks the same at this
     width — the topbar above it is the same navy — and drops a full-screen blur
     pass off the phone's compositor. */
  .header{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(8,20,44,.98)}
  .header.is-stuck{background:rgba(8,20,44,.99)}

  /* ---- Full-screen menu ----
     Full width, not a 360px drawer at the right edge. The submenus are the
     reason: a service group is 6–7 rows with an icon each, and inside a panel
     that narrow they had ~250px of measure — labels like "Family Income
     Benefit" wrapped, and the whole list read as a cramped second-class
     citizen of the row it hung off. Across the full screen each row gets one
     line, and the menu stops competing with the page behind it.

     `display:none` when closed is load-bearing, not tidiness. Parking the
     panel with transform:translateX(100%) alone leaves a fixed box sitting
     off the right edge, and a transform does not take a box out of the
     overflow calculation — so the document measured 725px wide on a 390px
     phone. A mobile browser that sees that widens the layout viewport to
     match, and then everything measured against the viewport is measured
     against the wrong number: the sticky bottom bar stretched past the
     screen and pushed "Book" out of view, the cookie notice took its full
     560px and hung off the right, and the sub-hero's white curve was
     drawn across 725px so the visible slice read as a straight line.

     Clipping the root instead (overflow-x:hidden or clip on <html>) does
     remove the scroll, but measured here it also stops .header from
     sticking — the root stops being the scrollport the sticky header
     resolves against. Both were tried; this is the one that fixes the
     overflow and keeps the header stuck.

     display is not animatable on its own, hence allow-discrete plus
     @starting-style: the panel is laid out first, then the transform runs.
     Browsers without those two simply show the menu instantly — the
     sheet loses its slide, nothing loses its layout.

     --gut is the sheet's one inline gutter: 20px on a phone, and past 640px
     it grows to keep the text column centred instead of letting rows stretch
     into a runway on a tablet. Every child indents to it — bar, rows, submenu
     — so one number keeps the whole sheet on a single left edge. */
  /* z-index:1 is not belt-and-braces. .hamburger.is-open animates its bars with
     a transform, and a transform makes each bar a stacking context painted in
     the same layer as a z-index:auto positioned box — so the tie broke on
     document order, and the burger, which comes after the nav, drew its white
     X on top of the sheet. Invisible over the white rows, a ghost over a
     tinted submenu. One step up settles it. */
  .nav{--gut:max(20px,calc((100% - 640px) / 2));z-index:1;
    position:fixed;inset:0;width:100%;background:#fff;flex-direction:column;align-items:stretch;justify-content:flex-start;
    padding:0 0 calc(26px + env(safe-area-inset-bottom,0px));gap:0;
    overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
    display:none;transform:translateX(100%);
    transition:transform .35s var(--ease),display .35s var(--ease) allow-discrete}
  .nav.is-open{display:flex;transform:translateX(0)}
  @starting-style{ .nav.is-open{transform:translateX(100%)} }

  /* The sheet covers the header it lives in, so it carries its own: the mark
     on the same navy, and the way out on the right where the burger was.
     Sticky, so a menu scrolled to the bottom still has its exit on screen. */
  .nav__bar{display:flex;align-items:center;justify-content:space-between;gap:12px;
    position:sticky;top:0;z-index:2;background:var(--navy-900);border-bottom:1px solid rgba(255,255,255,.1);
    padding:calc(11px + env(safe-area-inset-top,0px)) calc(var(--gut) - 7px) 11px var(--gut)}
  .nav__bar-logo{height:46px;width:auto;max-width:none;flex:none;display:block}
  .nav__close{display:grid;place-items:center;width:46px;height:46px;flex:none;
    border:1px solid rgba(255,255,255,.22);border-radius:12px;background:rgba(255,255,255,.07);color:#fff;
    transition:border-color .2s,color .2s,background .2s}
  .nav__close svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}
  .nav__close:hover{border-color:var(--gold-400);color:var(--gold-400);background:rgba(255,255,255,.12)}
  /* The gold focus ring is set by `.header :focus-visible` — right on the navy
     bar, and this sheet is inside that header, so it followed the rows onto
     white, where gold clears 3:1 by a hair and reads as decoration. Blue on the
     white part, gold kept where the ground is still navy. */
  .nav :focus-visible{outline-color:var(--blue-500)}
  .nav__bar :focus-visible{outline-color:var(--gold-400)}

  /* Hairlines between rows, not gaps between pills. At full width a floating
     rounded row has nothing to float against and the list reads as debris;
     a ruled list reads as a list. */
  .nav__list{flex-direction:column;align-items:stretch;gap:0;padding:0}
  .nav__list > li + li{border-top:1px solid var(--line)}
  /* display:flex, not the inline-flex the bar uses. Inline-flex shrinks the row
     to its label, and everything hung off that: the tap target ended at the end
     of the word, space-between parked the caret against the label instead of at
     the right edge, and the open-state tint drew a 160px tab rather than a row.
     56px floor on the height, since .9em around a 1.06rem line lands short of a
     comfortable target. */
  .nav__link{display:flex;padding:.9em var(--gut);min-height:56px;border-radius:0;font-size:1.06rem;
    justify-content:space-between;color:var(--ink)}
  .nav__link:hover{color:var(--blue-600);background:var(--bg-tint)}
  /* The desktop underline is drawn between the label's own edges. On a row that
     now runs the full width it stretches into a rule across the screen, which
     reads as a divider, not as "you are here" — a bar in the gutter says it
     without the ambiguity. aria-current carries it to a screen reader. */
  .nav__link.is-active{color:var(--blue-600);box-shadow:inset 3px 0 0 var(--gold-500)}
  .nav__link.is-active::after{content:none}
  .nav__caret{width:17px;height:17px;color:var(--muted)}
  /* The caret points at the state of the group, not at the pointer. Hover and
     focus-within both land on a parent row the moment it is tapped, so the
     desktop rules would flip the arrow up on a submenu that is still closed. */
  .nav__item--has:hover .nav__caret,
  .nav__item--has:focus-within .nav__caret{transform:none}
  .nav__item--has.is-expanded .nav__caret{transform:rotate(180deg)}
  .nav__item--has.is-expanded > .nav__link{color:var(--blue-600);background:var(--bg-tint)}

  /* Tinted and ruled, so an open group reads as being inside its parent row
     rather than as more top-level items. */
  .nav__mega,.nav__mega--wide{position:static;width:auto;opacity:1;visibility:visible;transform:none;
    box-shadow:none;border:none;border-radius:0;display:none;
    background:var(--bg-soft);border-top:1px solid var(--line)}
  /* Undoing the desktop open-state rules, which is not optional here: they are
     three-class selectors and beat the one-class reset above, and a tapped row
     matches both :hover (sticky on touch until the next tap) and :focus-within.
     The panel inherited translate(-50%,0) — half its own width to the left, so
     the submenu walked off the screen edge and the group looked empty. */
  .nav__item--has:hover .nav__mega,
  .nav__item--has:focus-within .nav__mega,
  .nav__item--has.is-open .nav__mega{transform:none}
  .nav__mega::before{display:none}
  .nav__item--has.is-expanded .nav__mega{display:block}
  .nav__mega-inner,.nav__mega-inner--wide{display:block;max-width:none;padding:8px var(--gut) 14px}
  .nav__mega-grp{margin:12px 0 6px}
  .nav__mega-grp--gap{margin-top:14px}
  .nav__mega-item{font-size:.99rem;padding:.55em 8px;margin-left:-8px;min-height:46px;border-radius:8px}
  .nav__mega-item:hover{transform:none;background:#fff}
  .nav__mega-feat,.nav__mega-bottom{display:none}
  .nav__cta{flex-direction:column;align-items:stretch;gap:12px;margin:0;
    border-top:1px solid var(--line);padding:20px var(--gut) 0}
  .nav__cta .btn{width:100%}
  .nav__tel{display:flex;align-items:center;gap:12px;min-height:56px;padding:10px 12px;
    border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--bg-soft);color:var(--ink)}
  .nav__tel svg{width:20px;height:20px;flex:none;fill:var(--blue-500)}
  .nav__tel small{display:block;font-size:.76rem;color:var(--muted);line-height:1.3}
  .nav__tel strong{display:block;font-family:var(--font-head);font-size:1.02rem;font-weight:700;color:var(--ink);line-height:1.3}
  .nav__tel:hover{border-color:var(--blue-500)}
  .nav__cta .btn--ghost{border-color:var(--line);color:var(--ink)}
  .nav__cta .btn--ghost:hover{border-color:var(--blue-500);color:var(--blue-600)}

  /* Scrim: below the header (z-index 100) so the bar and the drawer inside it
     stay lit, above everything else. It is also the tap-to-close target, which
     is what makes "tap outside" discoverable in the first place. */
  .nav-scrim{display:block;position:fixed;inset:0;z-index:98;background:rgba(6,16,36,.55);
    opacity:0;visibility:hidden;transition:opacity .3s var(--ease),visibility .3s}
  .is-nav-open .nav-scrim{opacity:1;visibility:visible}
  /* The floats duplicate what the open sheet already offers, and they would sit
     half-lit under the scrim. The burger goes with them: the sheet covers it and
     carries its own close button, so animating it into a second X only puts two
     of them on screen. */
  .is-nav-open .to-top,
  .is-nav-open .wa-float{opacity:0;pointer-events:none;transition:opacity .25s var(--ease)}
  .is-nav-open .hamburger{opacity:0;visibility:hidden;transition:opacity .25s var(--ease),visibility .25s}

  .hamburger{display:flex}
  .topbar__contact{gap:14px}
  .topbar__item--hide{display:none}
  /* The notice collapses here, not at the usual 620. Two columns of a
     ~810px container leave the warning about 330px wide — roughly 40
     characters a line, where the rag turns violent and the last line
     strands a word. It reads better stacked long before it has to. */
  .footer__notice{grid-template-columns:1fr;gap:26px}
  /* The CTA bar stacks here too, for the same reason and not at 620: the
     two buttons need 392px whatever the viewport, so below this the copy
     column falls under ~45 characters a line. Stacking on purpose looks
     composed; letting flex-wrap drop the buttons to their own row looks
     like the bar broke. */
  .cta-band__inner{flex-direction:column;align-items:flex-start}
  .cta-band__actions{width:100%}
  /* flex:1 would set flex-basis:0, and because .btn--primary is overflow:hidden
     its automatic minimum size resolves to 0 — the button then shrinks below its
     own label and clips it. Basis auto keeps the label intact and lets the row
     wrap instead. */
  .cta-band__actions .btn{flex:1 1 auto;min-width:fit-content}
}

/* ---------- Footer column count ----------
   All four steps live here, in descending order, because they only make sense
   read together. The breakpoints are where the longest labels — "Development
   Finance" and "Family Income Benefit" — start breaking onto two lines, which
   reads as a broken list rather than a wrapped one. Measured, not guessed: five
   columns hold to 1180, three to 700, two to 520.

   Plain max-width steps in cascade order, never a `(max-width) and (min-width)`
   band. Adjacent bounds like max-620/min-621 leave a dead zone — a viewport
   laying out at 620.5px satisfies neither, and the footer silently fell back to
   five 85px columns with every link wrapped. Cascade order has no such seam. */
@media (max-width:1180px){
  .footer__grid{grid-template-columns:repeat(3,1fr);gap:30px}
  .footer__col--brand{grid-column:1/-1}
}
@media (max-width:700px){
  .footer__grid{grid-template-columns:1fr 1fr}
}
@media (max-width:520px){
  .footer__grid{grid-template-columns:1fr;gap:0;padding:56px 24px 40px}

  /* ---- Link columns become an accordion ----
     Nineteen service links, one under the other, made the footer 2,060px tall
     on a 390px screen — a third of the whole page, and the contact details and
     the regulatory notice sat at the bottom of it. Collapsed, the same footer
     is about 700px and every heading is reachable without a scroll marathon.

     <details>, so it works with no JavaScript: the panels ship open (which is
     also what a crawler and a no-JS visitor get), and main.js closes them at
     this width on load. Contact stays open — it is the column people come down
     here for. */
  .footer__col--links{border-bottom:1px solid rgba(255,255,255,.09)}
  .footer__col--brand + .footer__col--links{border-top:1px solid rgba(255,255,255,.09)}
  .footer__col--brand{margin-bottom:22px}
  .footer__col--contact{margin-top:26px}
  .footer__col--links > summary{display:flex;align-items:center;justify-content:space-between;
    gap:14px;min-height:52px;padding:6px 0;cursor:pointer}
  .footer__col--links > summary h4{margin:0}
  .footer__col--links > summary::after{content:"";width:9px;height:9px;flex:none;margin-right:2px;
    border-right:2px solid var(--gold-400);border-bottom:2px solid var(--gold-400);
    transform:translateY(-2px) rotate(45deg);transition:transform .25s var(--ease)}
  .footer__col--links[open] > summary::after{transform:translateY(2px) rotate(-135deg)}
  .footer__col--links > ul{padding:2px 0 18px}
  .footer__col--links > ul a{display:block;padding:5px 0}
}

@media (max-width:620px){
  body{font-size:16px}
  .container{padding:0 18px}
  .section{padding:64px 0}
  .rail{padding:0}                     /* the stage keeps owning the rhythm */
  .rail__stage{padding:64px 0}
  .rail .section__head{margin-bottom:30px}
  .rail__foot{margin-top:26px;gap:14px}
  .why,.contact,.detail{padding:56px 0}
  .cards,.cards--3,.steps,.benefits__grid,.field-row,.why__stats,.features,.values,.about__stats{grid-template-columns:1fr}
  /* the four-across rule on home is more specific, so it needs undoing by name */
  .why .why__stats{grid-template-columns:1fr 1fr}
  .reviews--wall{columns:1}
  .reviews-summary__stats{grid-template-columns:1fr}
  .proof-strip{padding:20px}
  .proof-strip__cta{white-space:normal}
  .benefits{margin-top:-30px}
  .hero__inner{padding:64px 18px 76px}
  .subhero__inner{padding:40px 18px 46px}
  .foryou{padding:24px 22px}
  .calc{grid-template-columns:1fr}
  .calc__inputs{padding:26px 22px 30px}
  .calc__output{padding:28px 22px}
  .calc-tab{font-size:.85rem;padding:.7em .4em}
  .calc-tab svg{display:none}
  .cta-band__inner{padding:40px 18px}
  .wiz-cards{grid-template-columns:1fr}
  /* .wa-float is placed in the 680 block, where the sticky bar it has to clear
     is defined — two rules for the same offset drift apart. */
  .brand__logo{height:48px}
  .topbar__contact .topbar__item:nth-child(2){display:none}
  .footer__bottom-inner{flex-direction:column;text-align:center}
  /* the un-positioning this used to do now lives in the base rule */
  .footer__badges{flex-wrap:wrap}
  .footer__badges img{height:38px}
}

/* Five columns need the full container. Below it the link columns fall under
   ~155px and "Development Finance" and "Family Income Benefit" break onto two
   lines, which reads as a broken list rather than a wrapped one. Brand goes
   full width and the four remaining columns get room instead. */

@media (max-width:480px){
  /* .btn is white-space:nowrap, which is right on a normal screen and
     wrong on a 320px one: "Verify every review on Facebook" needs 301px
     of unbreakable line inside a 270px column, and the page scrolled
     sideways rather than the label wrapping. A button on two lines is
     not a defect; a page that pans is. */
  .btn{white-space:normal}

  /* Nine overlapping 46px avatars come to 310px — wider than the column
     at 320px. Smaller circles and a deeper overlap keep the same "a lot
     of people" read in 222px. */
  .faces img,.faces__more{width:38px;height:38px;margin-left:-15px}
  .faces__more{font-size:.74rem}
}

@media (max-width:400px){
  .why .why__stats{grid-template-columns:1fr}
}

@media (max-width:680px){
  /* No sticky call/book bar at this width, by the client's call: every page
     already closes on a CTA band and the service pages carry their own, so the
     bar repeated an offer the reader had just been given. Removing it takes the
     page's bottom reserve with it — the page now ends where the footer ends,
     with nothing parked over it and no strip of background left under it.
     The WhatsApp disc went the same way, and for the same reason it also rode
     over the left edge of whatever footer link it landed on. Both stay on
     tablet and desktop, where there is room and nothing to collide with. */
  .wa-float{display:none}
  .to-top{bottom:16px;right:16px}
  /* Back-to-top steps aside over the footer's last row, where it would sit on
     the copyright line and on two of the four legal links (main.js sets the
     class from an observer on .footer__bottom). */
  .is-at-page-end .to-top{opacity:0;visibility:hidden;pointer-events:none;transform:translateY(10px)}

  /* The consent notice is the first thing a phone visitor has to touch, so
     it gets full-width targets in reading order — accept and reject the
     same size, which is what PECR asks for anyway — and a height cap so a
     long notice on a short screen scrolls inside its own box instead of
     running off the top. */
  .cookie{max-height:calc(100vh - 140px);overflow-y:auto}
  .cookie__inner{padding:16px 18px}
  .cookie__actions{flex-direction:column;gap:8px}
  .cookie__actions .btn{width:100%;padding:.8em 1em}

  /* 22px of tappable height on a phone number is a miss waiting to
     happen. The padding grows the target without moving the text. */
  .topbar__item{padding:9px 0}
  .topbar__social a{width:34px;height:34px}
}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
  [data-reveal]{opacity:1;transform:none}
  /* the blanket rule above collapses the crossfade to its 0% frame, which is
     opacity:0 — every slide would vanish. Stop the loop on the first photo. */
  .hero__slide{animation:none!important;opacity:0;transform:none}
  .hero__slide:nth-child(1){opacity:1}

  /* Reviews stop travelling and become a plain scrollable row. The duplicate
     pass is dropped: with nothing moving it is just every quote printed twice. */
  .reviews-mq{overflow-x:auto;mask-image:none;-webkit-mask-image:none;scrollbar-width:none}
  .reviews-mq::-webkit-scrollbar{display:none}
  .reviews-mq__track{animation:none!important;transform:none!important}
  .reviews-mq__pass[aria-hidden="true"]{display:none}
}
