/* Self-hosted fonts (latin subsets, woff2) — no third-party requests.
   Source Sans 3 is a variable font: one file covers 200–900. */
@font-face {
  font-family: "Spectral";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("fonts/spectral-300.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Spectral";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/spectral-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Spectral";
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url("fonts/spectral-300-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("fonts/source-sans-3.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Sans 3";
  font-style: italic;
  font-weight: 200 900;
  font-display: swap;
  src: url("fonts/source-sans-3-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --paper: #F4F1EC;
  --ink: #2B2822;
  --cream: #F4F1EC;   /* constant: text on moss/dark surfaces, both themes */
  --greige: #A69B8D;
  --moss: #44604E;
  --moss-deep: #37503F;
  --muted: #5A5346;
  --hairline: rgba(166, 155, 141, 0.45);
  --serif: "Spectral", Georgia, serif;
  --sans: "Source Sans 3", "Gill Sans", "Segoe UI", sans-serif;
}

/* Dark theme: night hero pairs with a dark page. Toggled by the sun/moon
   button (persisted for the tab) or by the visitor's OS setting. */
html[data-mode="dark"] {
  /* Blue-slate, not brown. The whole night world is already blue - the hero
     photograph, its #0D111A sky gradient, and the band surfaces below - so a
     warm-brown ground put the page in a different world from its own
     furniture. This sits deeper than --moss-deep, so the bands still read as
     raised against it, and matches the old brown's luminance closely enough
     that every contrast ratio on the page is preserved. */
  --paper: #1B2230;
  /* Text stays warm cream. Warm on cool is the pairing that keeps the night
     mode feeling lamplit rather than clinical, and holds 13.7:1 on --paper. */
  --ink: #F1EEE7;
  /* Secondary text and rules follow the ground into blue: the old warm greige
     (#B3AA9A) reads yellow and dirty once it is no longer sitting on brown. */
  --muted: #A6ADBA;
  --hairline: rgba(158, 172, 194, 0.28);
  /* Night surfaces: the bands and buttons follow the night hero's blue-slate
     rather than daytime's meadow green, so the page stays in one world. */
  --moss: #3D4C60;
  --moss-deep: #2F3C4D;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation: none !important; transition: none !important; }
}

body {
  font-family: var(--sans);
  font-size: 1.0625rem;            /* 17px minimum */
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  /* Every type size here is in rem, so text zoom scales it while the viewport
     stays the same width: at 200% a heading reaches ~93px and single words
     ("conversation.", "Paperwork,") get wider than a narrow phone. break-word
     splits a word only when it cannot fit on a line of its own, so normal
     rendering is byte-identical and the page never scrolls sideways instead of
     reflowing (WCAG 1.4.4 / 1.4.10). */
  overflow-wrap: break-word;
}
@media (min-width: 700px) {
  body { font-size: 1.125rem; }    /* 18px on larger screens */
}

/* ---------- shared bits ---------- */

.col {
  max-width: 41rem;
  margin-inline: auto;
  padding-inline: 1.375rem;
}

.kicker {
  display: block;
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 1.1rem;
  line-height: 1.65;
}

h1, h2 {
  font-family: var(--serif);
  font-weight: 300;
  letter-spacing: -0.012em;
  /* Headings are where the zoomed long-word problem bites hardest, and body's
     break-word alone chopped "conversation." into "conversatio / n.". Both
     documents declare lang="en-GB", so the browser can hyphenate at a real
     syllable boundary and keep the word readable. Never fires at normal sizes:
     these words already fit. */
  hyphens: auto;
}
h2 {
  font-size: clamp(1.75rem, 1.35rem + 2vw, 2.4rem);
  line-height: 1.22;
  margin-bottom: 1.2rem;
}
/* Interior page titles: one step above section headings. */
.page-h {
  font-size: clamp(2rem, 1.5rem + 2.6vw, 2.9rem);
  line-height: 1.18;
  margin-bottom: 1.2rem;
}

p + p { margin-top: 1.05rem; }

.btn {
  display: inline-block;
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--cream);
  background: var(--moss);
  text-decoration: none;
  padding: 0.95rem 1.9rem;
  border-radius: 2.5rem;
  transition: background-color 0.25s ease;
}
.btn:hover, .btn:focus-visible { background: var(--moss-deep); }
.btn:focus-visible { outline: 2px solid var(--cream); outline-offset: 3px; }

.text-link {
  color: var(--ink);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}
.text-link:hover, .text-link:focus-visible { text-decoration-thickness: 2px; }

.after-list { margin-top: 2.2rem; }

section { padding-block: 4.25rem; }
@media (min-width: 700px) { section { padding-block: 5.5rem; } }

.rule { border: 0; border-top: 1px solid var(--hairline); }
/* .col padding sits inside the border box; without this the hairline
   overhangs the text column by the padding on each side. */
.rule.col { padding-inline: 0; width: min(100% - 2.75rem, 38.25rem); }

/* ---------- top bar (hero overlay on the landing page, plain header elsewhere) ---------- */

.hero-top {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem 1rem;
  padding: 1.25rem 1.375rem;
}
@media (min-width: 900px) { .hero-top { padding: 1.75rem 3rem; } }

.page-top { border-bottom: 1px solid var(--hairline); }

.hero-top-right {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.1rem;
}

.mode-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;   /* 44px tap target */
  height: 2.75rem;
  background: transparent;
  border: none;
  border-radius: 50%;
  color: inherit;
  cursor: pointer;
}
.mode-toggle svg { width: 1.25rem; height: 1.25rem; }
.mode-toggle:hover { background: rgba(128, 120, 104, 0.16); }
.mode-toggle:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.mode-toggle .icon-sun { display: none; }
html[data-mode="dark"] .mode-toggle .icon-sun { display: block; }
html[data-mode="dark"] .mode-toggle .icon-moon { display: none; }

.wordmark {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.3rem;
  letter-spacing: 0.015em;
  color: inherit;
  text-decoration: none;
}

.top-link {
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 0.15rem;
  white-space: nowrap;
}
/* The underline means one thing only: the page you are on. The CTA link is
   not permanently underlined; it still underlines on hover/focus like the
   rest. */
.top-link:hover, .top-link:focus-visible,
.top-link[aria-current="page"] { border-bottom-color: var(--ink); }
.top-link:focus-visible, .wordmark:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

/* Invisible hit-area extension: brings the slim nav links up to ~44px targets
   without touching the visual design. Scoped to a.wordmark: the footer's
   wordmark is a <span>, and the pseudo-element was reaching 10px down over the
   first line of the credentials and swallowing pointer events there. */
.top-link, a.wordmark, .hero-scroll { position: relative; }
.top-link::after, a.wordmark::after, .hero-scroll::after {
  content: "";
  position: absolute;
  inset: -10px -8px;
}

/* ---------- hero (survey plate: dark type on a pale sky, image fills the viewport) ---------- */

.hero {
  position: relative;
  /* Taller than any viewport state on purpose: 96svh left a cream strip at
     the bottom of the first screen, and lvh covers the mobile case where the
     browser chrome collapses and the viewport grows. The scroll cue, not a
     gap, is what says "there is more below". */
  min-height: 104svh;
  min-height: 104lvh;
  display: flex;
  flex-direction: column;
  isolation: isolate;
  color: var(--ink);
  overflow: hidden; /* contains the 1.06-scale landing drift */
}

/* ---------- load sequence ----------
   The page holds fog (bare paper) while the hero image loads; index.html adds
   html.hero-loading before first paint and swaps it out when the image is
   ready (or after a 2.5s failsafe). Everything settles on long ease-outs.
   Under prefers-reduced-motion the class is never added and the global
   transition kill applies. */

.hero-media {
  transition:
    opacity 2s cubic-bezier(0.22, 1, 0.36, 1),
    transform 2.8s cubic-bezier(0.22, 1, 0.36, 1);
}
.hero h1 {
  transition:
    opacity 1.4s cubic-bezier(0.22, 1, 0.36, 1) 0.9s,
    transform 1.4s cubic-bezier(0.22, 1, 0.36, 1) 0.9s;
}
.hero .lede {
  transition:
    opacity 1.4s cubic-bezier(0.22, 1, 0.36, 1) 1.25s,
    transform 1.4s cubic-bezier(0.22, 1, 0.36, 1) 1.25s,
    visibility 0s linear 1.25s;
}
.hero .hero-top {
  transition:
    opacity 1.4s cubic-bezier(0.22, 1, 0.36, 1) 1.6s,
    transform 1.4s cubic-bezier(0.22, 1, 0.36, 1) 1.6s,
    visibility 0s linear 1.6s;
}
.hero .hero-scroll {
  transition:
    opacity 1.4s cubic-bezier(0.22, 1, 0.36, 1) 1.95s,
    transform 1.4s cubic-bezier(0.22, 1, 0.36, 1) 1.95s,
    visibility 0s linear 1.95s;
}

/* visibility rides the same delays so links are never focusable or
   hit-testable while still invisible during the reveal ladder. */
html.hero-loading .hero-media { opacity: 0; transform: scale(1.06); }
html.hero-loading .hero h1 { opacity: 0; transform: translateY(14px); }
html.hero-loading .hero .lede { opacity: 0; transform: translateY(14px); visibility: hidden; }
html.hero-loading .hero .hero-top { opacity: 0; transform: translateY(-8px); visibility: hidden; }
html.hero-loading .hero .hero-scroll { opacity: 0; transform: translateY(10px); visibility: hidden; }

/* Two heroes, one valley: dawn for the light theme, night for the dark theme.
   Variants are chosen by pixel density, NOT viewport width: cover-cropping a
   16:9 frame into a tall phone viewport scales to fill the height, so a 390px
   phone needs ~1500 CSS px of source width — more than a 1440 desktop, not
   less. Selecting by width was upscaling a 1000px file about 3x on mobile and
   softening the sky. The plain background-image line is the fallback for
   browsers without image-set. */
.hero-media {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-size: cover;
  background-position: center top;
  background-repeat: no-repeat;
  background-color: #E6E4DB;
  background-image: url("hero-dawn-2000.jpg");
  background-image: image-set(
    url("hero-dawn-2000.webp") type("image/webp") 1x,
    url("hero-dawn-2752.webp") type("image/webp") 2x);
}
html[data-mode="dark"] .hero-media {
  background-color: #2A3140;
  background-image: url("hero-night-2000.jpg");
  background-image: image-set(
    url("hero-night-2000.webp") type("image/webp") 1x,
    url("hero-night-2752.webp") type("image/webp") 2x);
}

/* The night sky is dark where the dawn sky is pale, but its brighter bands
   pull the lede under 4.5:1 (pixel-sampled). Deepen the upper sky with a
   soft gradient — reads as night, works as contrast — and set the lede to
   full cream. Dark mode only; the dawn sky needs nothing. */
html[data-mode="dark"] .hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(13, 17, 26, 0.6) 0%,
    rgba(13, 17, 26, 0.45) 55%,
    rgba(13, 17, 26, 0) 80%);
}
html[data-mode="dark"] .hero .lede { color: var(--cream); }

.hero-copy {
  text-align: center;
  padding: 3.5rem 1.375rem 0;
}
@media (min-width: 900px) { .hero-copy { padding-top: 5.5rem; } }

.hero h1 {
  font-size: clamp(2.25rem, 1.5rem + 4vw, 3.9rem);
  line-height: 1.12;
  margin-bottom: 1rem;
  max-width: 24ch;
  margin-inline: auto;
  text-wrap: balance;
}
.hero .lede {
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  line-height: 1.6;
  max-width: 34rem;
  margin: 0 auto 2.1rem;
  color: var(--muted);
}

/* Slight ink backing so the cue never disappears into the fallback colour
   or a bright patch of the photograph. */
.hero-scroll {
  /* Pinned inside the FIRST viewport (100svh), not the hero's bottom edge:
     the hero is taller than the viewport now, so flowing this at the bottom
     would put it below the fold, where a scroll cue is no use to anyone. */
  position: absolute;
  left: 1.375rem;
  top: calc(100svh - 6.5rem);
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cream);
  text-decoration: none;
  background: rgba(43, 40, 34, 0.72);
  padding: 0.55rem 0.95rem;
  border-radius: 2rem;
}
@media (min-width: 900px) { .hero-scroll { left: 3rem; top: calc(100svh - 7rem); } }
.hero-scroll:hover { background: rgba(43, 40, 34, 0.88); }
.hero-scroll:focus-visible { outline: 2px solid var(--cream); outline-offset: 3px; }

.hero-spacer { flex: 1; min-height: 9rem; }

/* Interior pages settle in on arrival: one quick lift of the content, CSS
   only, nothing gated on it, disabled by the global reduced-motion rule. The
   masthead is deliberately NOT animated: staggering it read as a double page
   load, and its image can finish decoding mid-animation, which added a third
   visible "pop". One element, one movement. */
.page-top ~ main { animation: settle-rise 0.45s ease-out both; }
@keyframes settle-rise {
  from { opacity: 0; transform: translateY(10px); }
}

/* ---------- interior-page masthead: a slim slice of the valley so the
   photographic world survives the first click ---------- */

.masthead {
  height: 34vh;
  min-height: 200px;
  background-size: cover;
  background-position: center 30%;
  background-repeat: no-repeat;
  background-color: #E6E4DB;
  background-image: url("hero-dawn-1000.jpg");
  background-image: image-set(
    url("hero-dawn-1000.webp") type("image/webp"),
    url("hero-dawn-1000.jpg") type("image/jpeg"));
}
@media (min-width: 700px) {
  .masthead {
    background-image: url("hero-dawn-2000.jpg");
    background-image: image-set(
      url("hero-dawn-2000.webp") type("image/webp"),
      url("hero-dawn-2000.jpg") type("image/jpeg"));
  }
}
html[data-mode="dark"] .masthead {
  background-color: #2A3140;
  background-image: url("hero-night-1000.jpg");
  background-image: image-set(
    url("hero-night-1000.webp") type("image/webp"),
    url("hero-night-1000.jpg") type("image/jpeg"));
}
@media (min-width: 700px) {
  html[data-mode="dark"] .masthead {
    background-image: url("hero-night-2000.jpg");
    background-image: image-set(
      url("hero-night-2000.webp") type("image/webp"),
      url("hero-night-2000.jpg") type("image/jpeg"));
  }
}

/* ---------- steps ---------- */

.steps { list-style: none; margin-top: 2.4rem; }
.steps li {
  display: grid;
  /* minmax(0, 1fr), not 1fr: a bare 1fr floors at the content's min-content
     width, so at 200% zoom the step text refused to shrink inside its track and
     overflowed the page instead of wrapping. */
  grid-template-columns: 3rem minmax(0, 1fr);
  gap: 1.1rem;
  padding-block: 1.5rem;
  border-top: 1px solid var(--hairline);
}
.steps li:last-child { border-bottom: 1px solid var(--hairline); }
.steps .n {
  font-family: var(--serif);
  font-weight: 300;
  font-size: 1.9rem;
  line-height: 1.1;
  color: var(--muted);
}
.steps h3 {
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 600;
  margin-bottom: 0.3rem;
}
.steps p { color: var(--ink); }

/* ---------- fees & availability ---------- */

/* Same treatment as .steps h3 / .faq h3 / .footer-crisis h2, so the two
   subheads inside this section cost no new tokens. More space above than
   below: they open a topic rather than caption the paragraph under them. */
.fees h3 {
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 600;
  margin-top: 2.6rem;
  margin-bottom: 0.9rem;
}

/* Flex-wrap rather than a two-track grid: a grid track cannot wrap, so at 200%
   text zoom the day column plus the time would have had to overflow. Here the
   time drops onto its own line the moment it stops fitting, and no media query
   is involved (rem inside a media query does not reliably follow text zoom). */
.hours > div {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.1rem;
  padding-block: 0.7rem;
  border-top: 1px solid var(--hairline);
}
.hours > div:last-child { border-bottom: 1px solid var(--hairline); }
.hours dt { flex: 0 0 6rem; font-weight: 600; }
.hours dd { flex: 1 1 8rem; min-width: 0; color: var(--muted); }

/* Answers the question the table itself provokes ("can I book 6.30 on a
   Tuesday?"), so it belongs to the table, not to the next topic: tight above,
   and it keeps the muted register of the dd times it qualifies. */
.hours-note {
  margin-top: 0.85rem;
  font-size: 0.9375rem;
  color: var(--muted);
}

/* ---------- contact ---------- */

.contact-line {
  margin-top: 1.4rem;
  color: var(--muted);
}
/* An email address is one unbreakable word. At 200% text zoom
   hello@blythevalleycounselling.co.uk was 520px wide in a 302px column and
   pushed book.html 174px sideways. */
.contact-line a { color: var(--ink); overflow-wrap: anywhere; }
/* The phone route pairs with the email route above it. */
.contact-line + .contact-line { margin-top: 0.55rem; }

/* ---------- about ---------- */

.creds {
  margin-top: 1.8rem;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--muted);
  letter-spacing: 0.02em;
}
/* The further-training line is a second fine-print line, not a second topic:
   it reads as a continuation of the credentials above it, so it gets the
   paragraph gap rather than the section gap. */
.creds + .creds { margin-top: 0.5rem; }

/* The scroll cue's anchor: without this the browser puts the h2 flush at the
   top of the viewport, hiding the "Who you'll talk to" kicker above it. Stop
   short so the section arrives with its opening and some air intact. */
#about-h { scroll-margin-top: 8rem; }

/* Accreditation mark: quiet trust furniture, not content. Sits on a small
   white chip because the supplied PNG has a baked white ground and BACP rules
   forbid altering the mark; the chip reads intentionally in dark mode. */
/* Required small print, sized as small print: present and legible, never
   competing with the credentials it annotates. */
/* Centred, because it captions the centred mark row rather than the
   left-aligned prose above it. Left-aligned under two centred chips it read as
   a stray line of body copy that had drifted down the page. */
.mark-note {
  margin-top: 0.9rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--muted);
  max-width: 30rem;
  margin-inline: auto;
  text-align: center;
  text-wrap: balance;   /* two short centred lines beat one long and one stub */
}

.member-logo {
  margin-top: 1.6rem;
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  justify-content: center;   /* the chips read as a seal row, centred */
  gap: 1rem;
  /* Bounds the growth below, so the row cannot stretch to the full measure.
     34rem is the two basis widths plus the gap. */
  max-width: 34rem;
  margin-inline: auto;
}
/* Basis, not a fixed width: the img's natural size would otherwise set the
   basis and force a wrap. Growth is what makes the stacked case tidy - when a
   chip is alone on its line it takes the full row rather than sitting at its
   basis while its neighbour sits at a different one, which is what a media
   query would otherwise have to guess a breakpoint for. */
.member-logo picture {
  flex: 1 1 min(13rem, 100%);
  max-width: 100%;
}
/* The NCPS lockup is 3.2:1 where the BACP one is 2.2:1. At an equal basis the
   two chips would be the same width and visibly different heights, this one
   the shorter; 19rem lands them within about five pixels of the same height,
   which is the alignment the eye actually reads in a row of two marks. */
.member-logo .logo-ncps { flex: 1 1 min(19rem, 100%); }
.member-logo img {
  width: 100%;
  height: auto;
  background: #fff;
  padding: 0.7rem 0.9rem;
  border-radius: 6px;
}
/* .logo-slot, the dashed placeholder that held the NCPS seat, deleted
   2026-07-28: the real logo arrived and the row is now two real marks. */

/* Full training record: reference material, not narrative. It sits below the
   mark row so the section still ends on trust furniture rather than a list,
   and it is set at fine-print size deliberately - someone checking a
   counsellor's training will read 14px; nobody else needs to be sold it. Two
   columns above 34rem of content, because the two headings are a genuine pair
   and stacking them makes the shorter list look like an afterthought. */
.quals {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--hairline);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.5rem 2.5rem;
}
.quals h3 {
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 0.7rem;
}
.quals ul {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--muted);
}
/* Row gap, not a bullet: each entry is already a full line of title case, so
   space alone separates them and the column stays quiet. */
.quals li + li { margin-top: 0.45rem; }

/* Landing intro sits after the full-height hero: vast, minimal air around it.
   Single column: the portrait (and the two-column grid it required) was removed
   at Kuldip's request, WhatsApp 2026-07-26. */
.about { padding-block: 7rem; }
@media (min-width: 700px) { .about { padding-block: 10rem; } }

.faq { list-style: none; margin-top: 2.4rem; }
.faq li {
  padding-block: 1.5rem;
  border-top: 1px solid var(--hairline);
}
.faq li:last-child { border-bottom: 1px solid var(--hairline); }
.faq h3 {
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 600;
  margin-bottom: 0.3rem;
}

/* ---------- jump CTA ----------
   The hero deliberately carries no button: its whole argument is uninterrupted
   sky. This appears once the hero has scrolled away, so the primary action is
   never more than a thumb-reach from anywhere below the fold. */

.jump-cta {
  position: fixed;
  z-index: 20;
  bottom: 1.1rem;
  right: 1.375rem;
  display: block;
  text-align: center;
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--cream);
  background: var(--moss);
  text-decoration: none;
  padding: 0.9rem 1.9rem;
  border-radius: 2.5rem;
  box-shadow: 0 6px 24px rgba(43, 40, 34, 0.22);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(0.9rem);
  transition:
    opacity 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    visibility 0s linear 0.45s;
}
/* Shown between leaving the hero and reaching the real CTA button (theme.js
   watches .book .btn, not the band — the band is taller than a phone viewport,
   so watching it hid the pill a full screen early). Once the button is on
   screen a floating duplicate of a visible button is just noise on the copy.
   The footer is a second stand-down trigger, and it is not redundant: at 200%
   text zoom the footer is taller than the viewport, so the button never comes
   into view, .cta-onscreen never sets, and the pill sat on top of the
   registration line. Watching the footer catches that case at its cause. The
   max-height guard below cannot: text-only zoom leaves the viewport at its
   full CSS height. */
html.past-hero:not(.cta-onscreen):not(.footer-onscreen) .jump-cta {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
  transition-delay: 0s, 0s, 0s;
}
.jump-cta:hover { background: var(--moss-deep); }
.jump-cta:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
@media (min-width: 700px) {
  .jump-cta { bottom: 1.5rem; right: 3rem; }
}
/* A fixed bar eats too much of a landscape phone or a heavily zoomed page. */
@media (max-height: 460px) {
  .jump-cta { display: none; }
}

/* ---------- booking ---------- */

.book {
  background: var(--moss);
  color: var(--cream);
  /* The page's destination: a full quiet room to decide in, not a banner
     between bands. Its counterweight is the footer staying small, so the two
     moss surfaces read as different things at a glance. Left-aligned on the
     same column axis as every other section: with the three steps living
     here, a centred room would put two alignments on one page. */
  min-height: 60svh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-block: 5rem;
}
/* A flex item defaults to min-width: auto, so it refuses to shrink below its
   own min-content width. At 200% text zoom the CTA button's intrinsic width
   plus this column's gutters exceeded the viewport and the whole page picked up
   horizontal scroll (WCAG 1.4.10). min-width: 0 lets the column shrink to the
   band and the button wrap, which is what reflow is supposed to do. */
.book > .col { min-width: 0; }
.book h2 { margin-bottom: 1rem; }
.book .kicker { color: rgba(244, 241, 236, 0.85); }
.book p {
  margin-bottom: 2.1rem;
  color: rgba(244, 241, 236, 0.92);
}
.book .text-link { color: inherit; }   /* page ink would sink into the moss */

/* .cta-note, .write-line and .faq-line deleted 2026-07-28 with the four
   paragraphs they styled. The band ends on the button now; book.html owns the
   routes. */
.book .btn {
  background: var(--cream);
  color: #2B2822;
}
.book .btn:hover, .book .btn:focus-visible { background: #FFFDF8; }

/* The three steps inside the band, tinted from the band's cream rather
   than the page inks. */
.book .steps {
  margin-top: 0;
  margin-bottom: 2.6rem;
}
.book .steps li { border-top-color: rgba(244, 241, 236, 0.25); }
.book .steps li:last-child { border-bottom-color: rgba(244, 241, 236, 0.25); }
.book .steps .n { color: rgba(244, 241, 236, 0.7); }
.book .steps p {
  max-width: none;      /* undo .book p's 30rem centring */
  margin-bottom: 0;
  color: rgba(244, 241, 236, 0.92);
}

/* ---------- footer ----------
   Carries the crisis information. It used to sit between the closing copy and
   the CTA, which made a disclaimer and an emergency number the last thing a
   hesitant visitor read before deciding. Here it is still on every page and
   still one scroll from anywhere, without standing in the path. Keeping it in
   the footer band also means the page moves paper -> moss -> moss-deep: one
   transition into colour rather than alternating stripes. */

footer {
  background: var(--moss-deep);
  color: var(--cream);
  /* Deliberately compact: crisis signposting must be findable without being
     the emotional centre of the page (PRODUCT.md principle 3). */
  padding: 2.2rem 1.375rem 2rem;
}

.footer-inner { max-width: 41rem; margin-inline: auto; }

/* Two columns once there is room: the crisis routes and the practice facts stop
   being one long column of small cream type, and the footer gets SHORTER for
   carrying more. DOM order runs left to right, so reading order, tab order and
   visual order all agree. */
@media (min-width: 760px) {
  .footer-inner {
    max-width: 58rem;
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }
}

.footer-crisis {
  /* It is a <section>, so the generic section padding-block would otherwise
     add 5.5rem of air above the heading and inflate the whole footer. */
  padding-block: 0;
}
/* Was .kicker: 13px uppercase tracked, which made the one safety-critical
   heading on the site the smallest type in the footer. This is the same
   treatment as .steps h3 / .faq h3, so it costs no new tokens. */
.footer-crisis h2 {
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: normal;
  line-height: 1.65;
  margin-bottom: 0.5rem;
  color: var(--cream);
}

/* 1.45, not the body's 1.65: these are one-line list rows, not prose, and the
   inherited paragraph leading padded the block by four lines' worth of air. */
.crisis-routes { list-style: none; color: var(--cream); line-height: 1.45; }
/* Generous separation, and deliberately NO invisible hit-area extension of the
   kind .top-link gets: overlapping targets that dial 999 and 111 are worse than
   small ones. Each link clears the 24px WCAG 2.2 minimum on its own. */
.crisis-routes li + li { margin-top: 0.55rem; }
.crisis-routes a {
  color: var(--cream);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.crisis-routes a:focus-visible,
.footer-reach a:focus-visible,
.footer-facts a:focus-visible {
  outline: 2px solid var(--cream);
  outline-offset: 3px;
}
/* The boundary statement sits after the help, not in front of it. */
.crisis-note {
  margin-top: 0.85rem;
  font-size: 0.9375rem;
  color: rgba(244, 241, 236, 0.85);
}

/* Only the digits resist breaking. Applying nowrap to the whole link pushed
   "Samaritans free on 116 123" past a 390px viewport at 200% text zoom. */
.nb { white-space: nowrap; }

/* A hairline, not a card. Safety information and trading boilerplate had
   identical visual status with 3.4rem of whitespace as their only separation;
   NCPS uses a bordered card for the same job, which costs more height than this
   footer is willing to spend. On two columns the divider turns vertical. */
.footer-id {
  margin-top: 1.15rem;
  padding-top: 1.15rem;
  border-top: 1px solid rgba(244, 241, 236, 0.22);
}
@media (min-width: 760px) {
  .footer-id {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
    border-left: 1px solid rgba(244, 241, 236, 0.22);
    padding-left: 3rem;
  }
}
.footer-id .wordmark { display: block; font-size: 1.15rem; margin-bottom: 0.35rem; }

/* Wrapping list, not a middot-chained paragraph: a fact never splits across a
   line, and a screen reader gets item boundaries and a count instead of one
   nineteen-word run. The old 0.06em tracking is gone with it, which is what
   paid for the lines these two lists added. */
.footer-facts {
  list-style: none;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: rgba(244, 241, 236, 0.85);
}
.footer-facts + .footer-facts { margin-top: 0.35rem; }

/* Narrow screens: a plain stack, no separators. Every fact takes its own line
   at this width, so a middot has nothing to separate and only adds noise. */
@media (min-width: 760px) {
  .footer-facts { display: flex; flex-wrap: wrap; column-gap: 0.45rem; }
  /* Separator trails its own item rather than leading the next one. Wrapped
     lines then begin with a word: a middot pushed to the front of a line was
     the exact untidiness the old centred credential chain had. */
  .footer-facts li:not(:last-child)::after {
    content: "·";
    margin-left: 0.4rem;
    color: rgba(244, 241, 236, 0.7);
  }
}
.footer-facts a { color: var(--cream); text-decoration: underline; text-underline-offset: 0.2em; }

/* 15px text gives a 21px inline box, under WCAG 2.2 SC 2.5.8's 24px floor.
   inline-block plus this padding lifts it to ~24.5px and still fits inside the
   1.65 line box, so it buys the target without adding a pixel of footer. */
.footer-facts a, .footer-reach a { display: inline-block; padding-block: 0.11rem; }

/* The footer's onward action. Without it the bottom of faq.html and book.html
   is a dead end whose only links are other organisations' phone numbers. */
.footer-reach {
  margin-top: 0.7rem;
  font-size: 0.9375rem;
  color: rgba(244, 241, 236, 0.85);
}
.footer-reach a {
  color: var(--cream);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.footer-reach span { margin-inline: 0.3rem; color: rgba(244, 241, 236, 0.7); }

.footer-privacy {
  margin-top: 0.55rem;
  font-size: 0.875rem;
  color: rgba(244, 241, 236, 0.75);
}
/* Two quiet closing lines, one pair: the accessibility offer sits with the
   privacy statement rather than reading as a third footer section. */
.footer-privacy + .footer-privacy { margin-top: 0.3rem; }
/* 14px text gives a 20px inline box; the same 0.11rem pad the other footer
   links use clears WCAG 2.2 SC 2.5.8 without adding footer height. */
.footer-privacy a {
  display: inline-block;
  padding-block: 0.11rem;
  color: var(--cream);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.footer-privacy a:focus-visible {
  outline: 2px solid var(--cream);
  outline-offset: 3px;
}

/* ---- The portrait ----
   Kuldip chose the photo over the no-photo layout (2026-07-27), so this is
   now the only About treatment; the comparison carousel that presented the
   two is gone. The figure floats right on wide screens with the credentials
   as its caption, and sits between the kicker and the greeting on phones. */

.portrait-fig {
  width: min(11.5rem, 58%);  /* phone: face between kicker and greeting */
  margin-bottom: 1.1rem;
}
.portrait {
  display: block;
  width: 100%;
  height: auto;              /* release the height attribute's hint */
  aspect-ratio: 4 / 5;
  object-fit: cover;
  /* arch top, echoing the hills of the mark; oversized radii resolve to a
     perfect half-circle crown */
  border-radius: 999px 999px 10px 10px;
}
html[data-mode="dark"] .portrait { filter: brightness(0.92) saturate(0.96); }
/* one credentials element at a time: caption on wide screens, the
   end-of-section line on phones */
.portrait-creds { display: none; }
@media (min-width: 700px) {
  .portrait-fig {
    float: right;
    width: 12.5rem;
    /* Dropped from 0.5rem: the crown used to sit level with the h2 cap height,
       which put the photo's full weight against the headline. Starting it
       around the first line of body copy lets the headline own its own line. */
    margin: 4.5rem 0 1.2rem 2.6rem;
  }
  .portrait-creds {
    display: block;
    margin-top: 0.9rem;
    line-height: 1.5;
  }
  .about-photo .inline-creds { display: none; }
  /* the figure can outrun the prose; nothing below may wrap beside it */
  .about-photo .member-logo { clear: both; }
}
