/* ==========================================================================
   Keana Care — Main stylesheet
   Sections:
     1.  Design tokens (CSS variables)
     2.  Reset & base
     3.  Layout helpers & typography
     4.  Buttons
     5.  Header / navigation
     6.  Hero
     7.  Stats band
     8.  About
     9.  Services
     10. Funding & steps
     11. FAQ accordion
     12. Contact & form
     13. Footer
     14. Back-to-top, modal, toasts
     15. Legal / inner pages
     16. Service pages (hub, detail, breadcrumb, CTA band)
     17. Mobile action bar
     18. Animations & reduced motion
     19. Responsive breakpoints
     20. Print
   ========================================================================== */


/* ==========================================================================
   1. DESIGN TOKENS
   ========================================================================== */
:root {
  /* Brand palette — taken from the logo lockup itself: the purple wordmark,
     the teal "Care" script and the pink heart. Every value below was contrast-
     checked against the surface it actually sits on; the ratios in the comments
     are the measured ones, so keep them honest if you change a value. */
  --plum-900: #26093F;
  /* deepest — footer ground */
  --plum-800: #481878;
  /* the logo's KEANA purple — 12.5:1 on white */
  --plum-700: #5E2490;
  --plum-600: #783C90;
  /* the logo's mid purple — 7.4:1 on white */

  --teal-700: #005C66;
  /* button hover */
  --teal-600: #00707B;
  /* primary — 5.8:1 with white text, 5.5:1 as a link */
  --teal-500: #00909C;
  /* the logo's Care teal — icons, borders, focus ring */
  --teal-400: #12B4B8;
  /* bright accent, dark backgrounds only */
  --teal-100: #D2EFF2;
  --teal-050: #EBF8FA;

  /* Aliases kept so brand-specific accents read as brand, not as UI chrome */
  --brand-purple: var(--plum-800);
  --brand-purple-mid: var(--plum-600);
  --brand-pink: #D8589C;
  /* the heart accent (decorative only) */

  --off-white: #F9F7FB;
  /* faint purple cast so it sits under the plums */
  --white: #FFFFFF;
  --ink-900: #1C1226;
  /* body text — 17.0:1 on off-white */
  --ink-700: #4A3D57;
  /* secondary text — 9.4:1 on off-white */
  --ink-500: #6C5F78;
  /* muted text — 5.6:1 on off-white */
  --line: #E5DEEC;
  --line-strong: #CCC0D9;

  --danger: #B3261E;
  --danger-bg: #FDECEA;
  --success: #10715C;
  --success-bg: #E4F5F0;

  /* Typography — a warm serif carries the headlines, the humanist sans does
     all the work. The contrast between the two is what stops the page reading
     like a template. Fraunces' soft, slightly irregular shapes were picked over
     a crisp editorial serif because this brand should feel human, not corporate. */
  --font-display: 'Fraunces', 'Iowan Old Style', Georgia, 'Times New Roman', serif;
  --font-body: 'Nunito Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --fs-base: 1.0625rem;
  /* 17px — comfortably above the 16px floor */
  --lh-base: 1.7;

  /* Fluid type scale */
  --fs-xs: 0.9375rem;
  /* 15px — captions only */
  --fs-sm: 1rem;
  /* 16px */
  --fs-md: 1.125rem;
  /* 18px */
  /* The vw term is multiplied by --a11y-zoom (set by the accessibility
     toolbar) so headings grow with the text-size control too — rem alone
     only moves the floor and ceiling, never the fluid middle. */
  --fs-lg: clamp(1.25rem, 0.5vw * var(--a11y-zoom, 1) + 1.1rem, 1.4rem);
  --fs-h3: clamp(1.3rem, 0.7vw * var(--a11y-zoom, 1) + 1.1rem, 1.55rem);
  --fs-h2: clamp(1.75rem, 2vw * var(--a11y-zoom, 1) + 1.1rem, 2.6rem);
  --fs-h1: clamp(2.15rem, 3.6vw * var(--a11y-zoom, 1) + 1.1rem, 3.85rem);

  /* Spacing */
  --space-1: 0.375rem;
  --space-2: 0.75rem;
  --space-3: 1.125rem;
  --space-4: 1.75rem;
  --space-5: 2.5rem;
  --space-6: 3.5rem;
  --space-7: 5rem;
  --section-y: clamp(3.5rem, 7vw, 6.5rem);

  /* Radii */
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-pill: 999px;

  /* Elevation */
  --shadow-sm: 0 1px 2px rgba(6, 24, 47, .06), 0 2px 6px rgba(6, 24, 47, .05);
  --shadow-md: 0 6px 16px rgba(6, 24, 47, .08), 0 2px 6px rgba(6, 24, 47, .05);
  --shadow-lg: 0 18px 44px rgba(6, 24, 47, .14), 0 6px 14px rgba(6, 24, 47, .07);

  /* Layout */
  --container: 1200px;
  --container-narrow: 820px;
  --gutter: clamp(1.1rem, 4vw, 2.5rem);

  --transition: 220ms cubic-bezier(.4, 0, .2, 1);
}


/* ==========================================================================
   2. RESET & BASE
   ========================================================================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* Offset anchor targets so the sticky header never covers a heading */
  scroll-padding-top: 7.6rem;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  color: var(--ink-900);
  background: var(--off-white);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Locks background scroll while the mobile menu or modal is open.
   Pinning the body with `position: fixed` would also work, but it drags the
   sticky header (and with it the close button) off-screen, so the lock stays
   on `overflow` and the drawer blocks touch-scroll itself — see .nav-backdrop. */
body.is-locked {
  overflow: hidden;
}

img,
svg {
  max-width: 100%;
  height: auto;
  display: block;
}

h1,
h2,
h3,
h4 {
  margin: 0 0 var(--space-2);
  line-height: 1.22;
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--plum-800);
  text-wrap: balance;
}

/* Display sizes are serif; h3/h4 stay sans so cards and labels keep their
   scannability. Two roles, clearly separated — not serif everywhere. */
h1,
h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-optical-sizing: auto;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.hero__title,
.page-hero h1 {
  font-weight: 600;
}

p {
  margin: 0 0 var(--space-3);
}

p:last-child {
  margin-bottom: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
}

a {
  color: var(--teal-600);
  text-underline-offset: 3px;
  transition: color var(--transition);
}

a:hover {
  color: var(--plum-700);
}

/* Visible, consistent focus ring for keyboard users */
:focus-visible {
  outline: 3px solid var(--teal-500);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Screen-reader-only utility */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Skip link — visible once focused */
.skip-link {
  position: absolute;
  left: 50%;
  top: -100px;
  transform: translateX(-50%);
  z-index: 200;
  background: var(--plum-800);
  color: var(--white);
  padding: .85rem 1.5rem;
  border-radius: 0 0 var(--r-md) var(--r-md);
  font-weight: 700;
  text-decoration: none;
  transition: top var(--transition);
}

.skip-link:focus {
  top: 0;
  color: var(--white);
}

/* Honeypot field — off-screen but not display:none (bots skip hidden inputs) */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}


/* ==========================================================================
   3. LAYOUT HELPERS & TYPOGRAPHY
   ========================================================================== */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container--narrow {
  max-width: var(--container-narrow);
}

.section {
  padding-block: var(--section-y);
}

.section--tint {
  background: var(--white);
}

.section__head {
  max-width: 720px;
  margin: 0 auto clamp(2.25rem, 4vw, 3.5rem);
  text-align: center;
}

.section__title {
  font-size: var(--fs-h2);
}

.section__lede {
  font-size: var(--fs-md);
  color: var(--ink-700);
}

/* Small uppercase label above headings */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin: 0 0 var(--space-2);
  font-size: var(--fs-sm);
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--teal-600);
}

.eyebrow i {
  color: var(--brand-purple-mid);
}

.card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  box-shadow: var(--shadow-sm);
}

.card__title {
  display: flex;
  align-items: center;
  gap: .65rem;
  font-size: var(--fs-h3);
}

.card__title i {
  color: var(--teal-500);
}

/* Reusable tick list */
.check-list {
  list-style: none;
  margin-top: var(--space-3);
  display: grid;
  gap: .7rem;
}

.check-list li {
  display: flex;
  gap: .7rem;
  align-items: flex-start;
  color: var(--ink-700);
}

.check-list i {
  color: var(--teal-500);
  margin-top: .35rem;
  flex-shrink: 0;
}


/* ==========================================================================
   4. BUTTONS
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  padding: .85rem 1.6rem;
  border: 2px solid transparent;
  border-radius: var(--r-pill);
  font: inherit;
  font-weight: 800;
  font-size: var(--fs-sm);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition), color var(--transition),
    transform var(--transition), box-shadow var(--transition),
    border-color var(--transition);
}

.btn:hover {
  transform: translateY(-2px);
}

.btn:active {
  transform: translateY(0);
}

.btn--primary {
  background: var(--teal-600);
  color: var(--white);
  box-shadow: var(--shadow-sm);
}

.btn--primary:hover {
  background: var(--teal-700);
  color: var(--white);
  box-shadow: var(--shadow-md);
}

.btn--ghost {
  background: transparent;
  color: var(--plum-800);
  border-color: var(--line-strong);
}

.btn--ghost:hover {
  background: var(--white);
  border-color: var(--plum-800);
  color: var(--plum-800);
}

.btn--light {
  background: var(--white);
  color: var(--plum-800);
}

.btn--light:hover {
  background: var(--teal-050);
  color: var(--plum-800);
}

.btn--lg {
  padding: 1.05rem 2rem;
  font-size: var(--fs-md);
}

.btn--block {
  width: 100%;
}

/* Loading state used by the form while "sending" */
.btn.is-loading {
  pointer-events: none;
  opacity: .85;
}

.btn.is-loading .btn__label::after {
  content: '';
  display: inline-block;
  width: .95em;
  height: .95em;
  margin-left: .55em;
  vertical-align: -.15em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}


/* ==========================================================================
   5. HEADER / NAVIGATION
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--white);
  border-bottom: 1px solid var(--line);
  transition: box-shadow var(--transition);
}

.site-header.is-stuck {
  box-shadow: var(--shadow-md);
}

/* Slim contact strip */
.topbar {
  background: #DCCAEE;
  color: var(--plum-800);
  font-size: var(--fs-sm);
}

.topbar__inner {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem 1.75rem;
  justify-content: flex-end;
  padding-block: .5rem;
}

.topbar__item {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  color: var(--plum-800);
  text-decoration: none;
  font-weight: 600;
}

.topbar__item:hover {
  color: var(--teal-700);
}

.topbar__item i {
  color: var(--teal-600);
}

.topbar__item--muted {
  color: var(--ink-700);
}

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 94px;
}

/* Brand — the logo lockup image (emblem + wordmark) */
.brand {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  flex-shrink: 0;
  /* Keeps the tap target comfortable on touch devices */
  padding-block: .25rem;
}

.brand__logo {
  /* Intrinsic file is 640x194 (3.3:1); height drives the size, width follows.
     Sized so the "SUPPORT SERVICES" line under the wordmark stays legible. */
  height: 78px;
  width: auto;
  display: block;
}

/* Hamburger */
.nav__toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 48px;
  height: 48px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  cursor: pointer;
}

.nav__bar {
  display: block;
  width: 22px;
  height: 2.5px;
  margin-inline: auto;
  border-radius: 2px;
  background: var(--plum-800);
  transition: transform var(--transition), opacity var(--transition);
}

/* Morph bars into an X when open */
.nav__toggle[aria-expanded="true"] .nav__bar:nth-child(1) {
  transform: translateY(7.5px) rotate(45deg);
}

.nav__toggle[aria-expanded="true"] .nav__bar:nth-child(2) {
  opacity: 0;
}

.nav__toggle[aria-expanded="true"] .nav__bar:nth-child(3) {
  transform: translateY(-7.5px) rotate(-45deg);
}

/* Menu */
.nav__menu {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.nav__list {
  display: flex;
  /* Stretch so a dropdown anchored at `top: 100%` lands on the header edge
     with no dead gap for the pointer to fall through. */
  align-items: stretch;
  gap: .35rem;
  list-style: none;
}

.nav__list>li {
  display: flex;
  align-items: center;
}

.nav__link {
  display: block;
  padding: .6rem .9rem;
  border-radius: var(--r-sm);
  color: var(--plum-800);
  font-weight: 700;
  font-size: var(--fs-sm);
  text-decoration: none;
  position: relative;
}

.nav__link:hover {
  background: var(--teal-050);
  color: var(--teal-600);
}

.nav__link.is-active {
  color: var(--teal-600);
}

/* The underline lives on every link and wipes in from the left — on hover, and
   permanently once the link is the current section or page. */
.nav__link::after {
  content: '';
  position: absolute;
  left: .9rem;
  right: .9rem;
  bottom: .25rem;
  height: 3px;
  border-radius: 3px;
  background: var(--teal-500);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--transition);
}

.nav__link:hover::after,
.nav__link.is-active::after {
  transform: scaleX(1);
}

/* ---- Services dropdown ---------------------------------------------------
   A link plus a separate disclosure button: the label stays a real link to the
   services hub, and the chevron is the only thing that toggles the panel — so
   keyboard users are never forced through a menu to reach the page itself. */
.nav__item--has-menu {
  position: relative;
}

.nav__item--has-menu .nav__link {
  padding-right: .35rem;
}

.nav__submenu-toggle {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: var(--r-sm);
  color: var(--plum-800);
  font-size: .8rem;
  cursor: pointer;
  transition: transform var(--transition), background var(--transition), color var(--transition);
}

.nav__submenu-toggle:hover {
  background: var(--teal-050);
  color: var(--teal-600);
}

.nav__submenu-toggle[aria-expanded="true"] {
  transform: rotate(180deg);
  color: var(--teal-600);
}

.nav__dropdown {
  position: absolute;
  top: 100%;
  left: -.5rem;
  width: 340px;
  padding: .5rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity var(--transition), transform var(--transition), visibility var(--transition);
  z-index: 120;
}

.nav__item--has-menu.is-open .nav__dropdown {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.nav__dropdown ul {
  list-style: none;
  display: grid;
  gap: .1rem;
}

/* Rows cascade in behind the panel rather than all arriving at once */
.nav__dropdown li {
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 200ms ease, transform 200ms ease;
}

.nav__item--has-menu.is-open .nav__dropdown li {
  opacity: 1;
  transform: none;
}

.nav__item--has-menu.is-open .nav__dropdown li:nth-child(1) {
  transition-delay: 40ms;
}

.nav__item--has-menu.is-open .nav__dropdown li:nth-child(2) {
  transition-delay: 75ms;
}

.nav__item--has-menu.is-open .nav__dropdown li:nth-child(3) {
  transition-delay: 110ms;
}

.nav__item--has-menu.is-open .nav__dropdown li:nth-child(4) {
  transition-delay: 145ms;
}

.nav__item--has-menu.is-open .nav__dropdown li:nth-child(5) {
  transition-delay: 180ms;
}

.nav__item--has-menu.is-open .nav__dropdown li:nth-child(6) {
  transition-delay: 215ms;
}

.nav__dropdown a {
  display: flex;
  align-items: flex-start;
  gap: .75rem;
  padding: .7rem .8rem;
  border-radius: var(--r-sm);
  color: var(--plum-800);
  text-decoration: none;
  font-size: var(--fs-sm);
  font-weight: 700;
  line-height: 1.35;
}

.nav__dropdown a:hover,
.nav__dropdown a:focus-visible {
  background: var(--teal-050);
  color: var(--teal-600);
}

.nav__dropdown a i {
  width: 1.4rem;
  margin-top: .15rem;
  flex-shrink: 0;
  color: var(--teal-600);
  text-align: center;
}

.nav__dropdown a small {
  display: block;
  font-weight: 600;
  font-size: var(--fs-xs);
  color: var(--ink-500);
}

.nav__dropdown a:hover small {
  color: var(--ink-700);
}

/* The "view everything" row at the foot of the panel */
.nav__dropdown li:last-child a {
  margin-top: .25rem;
  border-top: 1px solid var(--line);
  border-radius: 0 0 var(--r-sm) var(--r-sm);
  color: var(--teal-600);
}


/* ==========================================================================
   6. HERO
   ========================================================================== */
.hero {
  position: relative;
  padding-block: clamp(3rem, 7vw, 6rem) clamp(3.5rem, 8vw, 6.5rem);
  background:
    radial-gradient(60rem 34rem at 88% -12%, var(--teal-100) 0%, rgba(220, 242, 241, 0) 62%),
    linear-gradient(180deg, var(--white) 0%, var(--off-white) 100%);
  overflow: hidden;
}

.hero__inner {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
}

.hero__title {
  font-size: var(--fs-h1);
  margin-bottom: var(--space-3);
}

.hero__subtitle {
  font-size: clamp(1.075rem, .6vw * var(--a11y-zoom, 1) + 1rem, 1.3rem);
  color: var(--ink-700);
  max-width: 34ch;
  margin-bottom: var(--space-4);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}

.hero__trust {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .6rem 1.5rem;
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
}

.hero__trust li {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-weight: 700;
  font-size: var(--fs-sm);
  color: var(--ink-700);
}

.hero__trust i {
  color: var(--teal-600);
}

/* Decorative visual */
.hero__visual {
  position: relative;
  min-height: 380px;
  display: grid;
  place-items: center;
}

.hero__blob {
  position: absolute;
  inset: 8% 4%;
  background: linear-gradient(140deg, var(--plum-700), var(--teal-500));
  border-radius: 46% 54% 38% 62% / 52% 42% 58% 48%;
  opacity: .95;
  animation: morph 14s ease-in-out infinite;
}

.hero__card {
  position: relative;
  z-index: 1;
  background: var(--white);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
}

.hero__card--main {
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: 320px;
  padding: 1.35rem 1.5rem;
}

.hero__avatar {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--teal-100);
  color: var(--teal-600);
  font-size: 1.35rem;
}

.hero__card-title {
  margin: 0;
  font-weight: 800;
  color: var(--plum-800);
}

.hero__card-text {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--ink-700);
  line-height: 1.5;
}

.hero__card--float {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding: .8rem 1.15rem;
  border-radius: var(--r-pill);
  font-weight: 800;
  font-size: var(--fs-sm);
  color: var(--plum-800);
  white-space: nowrap;
}

.hero__card--float i {
  color: var(--teal-600);
}

.hero__card--one {
  top: 6%;
  left: 0;
  animation: float 6s ease-in-out infinite;
}

.hero__card--two {
  bottom: 7%;
  right: 0;
  animation: float 6s ease-in-out infinite 1.6s;
}


/* ==========================================================================
   7. STATS BAND
   ========================================================================== */
.stats {
  background: var(--plum-800);
  padding-block: clamp(2rem, 4vw, 3rem);
}

.stats__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-3);
  text-align: center;
}

.stat {
  padding-inline: .5rem;
  border-left: 1px solid rgba(255, 255, 255, .14);
}

.stat:first-child {
  border-left: 0;
}

.stat__num {
  display: block;
  font-size: clamp(1.9rem, 3vw * var(--a11y-zoom, 1), 2.6rem);
  font-weight: 800;
  line-height: 1.1;
  color: var(--teal-400);
}

.stat__label {
  display: block;
  margin-top: .3rem;
  font-size: var(--fs-sm);
  color: #DACCEA;
}


/* ==========================================================================
   8. ABOUT
   ========================================================================== */
.about__grid {
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: clamp(1.25rem, 3vw, 2.25rem);
  align-items: start;
}

.about__highlights {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1rem, 2vw, 1.5rem);
}

/* Full-width row under the photo/mission split */
.about__highlights--row {
  grid-template-columns: repeat(4, 1fr);
  margin-top: clamp(1.5rem, 4vw, 3rem);
}

@media (max-width: 960px) {
  .about__highlights--row {
    grid-template-columns: repeat(2, 1fr);
  }
}

.highlight {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 1.6rem 1.5rem;
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}

.highlight:hover {
  transform: translateY(-4px);
  border-color: var(--teal-400);
  box-shadow: var(--shadow-md);
}

.highlight__icon {
  display: grid;
  place-items: center;
  width: 50px;
  height: 50px;
  margin-bottom: var(--space-2);
  border-radius: 14px;
  background: var(--teal-050);
  color: var(--teal-600);
  font-size: 1.25rem;
}

.highlight h3 {
  font-size: var(--fs-lg);
}

.highlight p {
  font-size: var(--fs-sm);
  color: var(--ink-700);
  margin: 0;
}


/* ==========================================================================
   9. SERVICES
   ========================================================================== */
.services__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(1.1rem, 2.2vw, 1.75rem);
}

.service-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--off-white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(1.5rem, 2.5vw, 2rem);
  overflow: hidden;
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}

/* The card fill is off-white, which reads on a white (--tint) section. On an
   off-white section it would vanish, so it flips to white instead. */
.section:not(.section--tint) .service-card:not(.service-card--cta) {
  background: var(--white);
}

/* Teal bar that grows across the top on hover */
.service-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 4px;
  background: var(--teal-500);
  transition: width var(--transition);
}

.service-card:hover {
  transform: translateY(-5px);
  border-color: var(--teal-400);
  box-shadow: var(--shadow-md);
}

.service-card:hover::before {
  width: 100%;
}

.service-card__icon {
  display: grid;
  place-items: center;
  width: 58px;
  height: 58px;
  margin-bottom: var(--space-3);
  border-radius: 16px;
  background: linear-gradient(135deg, var(--teal-500), var(--plum-700));
  color: var(--white);
  font-size: 1.4rem;
}

.service-card__title {
  font-size: var(--fs-h3);
}

.service-card p {
  color: var(--ink-700);
  font-size: var(--fs-sm);
}

.tag-list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: auto;
  padding-top: var(--space-3);
}

.tag-list--tight {
  margin-top: 0;
}

.tag-list li {
  padding: .3rem .8rem;
  border-radius: var(--r-pill);
  background: var(--teal-100);
  color: var(--plum-700);
  font-size: var(--fs-xs);
  font-weight: 700;
}

/* "Learn more" row — the whole card becomes the click target via ::after,
   but only the link text is announced, so screen readers get one clean link. */
.service-card__more {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin-top: var(--space-3);
  font-weight: 800;
  font-size: var(--fs-sm);
  color: var(--teal-600);
  text-decoration: none;
}

.service-card__more::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.service-card__more i {
  transition: transform var(--transition);
}

.service-card:hover .service-card__more {
  color: var(--teal-700);
}

.service-card:hover .service-card__more i {
  transform: translateX(4px);
}

/* The card's own outline follows the link's keyboard focus */
.service-card:has(.service-card__more:focus-visible) {
  outline: 3px solid var(--teal-500);
  outline-offset: 3px;
}

.service-card__more:focus-visible {
  outline: none;
}

/* Push the tags above the link when both are present */
.service-card:has(.service-card__more) .tag-list {
  margin-top: auto;
}

/* CTA tile */
.service-card--cta {
  background: linear-gradient(140deg, var(--plum-800), var(--teal-600));
  border-color: transparent;
  color: #E6F1F3;
  justify-content: center;
}

.service-card--cta .service-card__title {
  color: var(--white);
}

.service-card--cta p {
  color: #D3E7EA;
}

.service-card--cta .btn {
  margin-top: var(--space-3);
  align-self: flex-start;
}

.service-card--cta::before {
  background: var(--teal-400);
}


/* ==========================================================================
   10. FUNDING & STEPS
   ========================================================================== */
.callout {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  max-width: 940px;
  margin: 0 auto clamp(2rem, 4vw, 3rem);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  border: 2px solid var(--teal-400);
  border-left-width: 8px;
  border-radius: var(--r-lg);
  background: var(--teal-050);
  box-shadow: var(--shadow-sm);
}

.callout__icon {
  font-size: 1.75rem;
  color: var(--teal-600);
  line-height: 1;
  margin-top: .15rem;
  flex-shrink: 0;
}

.callout__title {
  font-size: var(--fs-h3);
}

.callout p {
  color: var(--ink-700);
  margin: 0;
}

.funding__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(1.1rem, 2.2vw, 1.75rem);
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}

.funding-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(1.5rem, 2.5vw, 2rem);
  text-align: center;
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition);
}

.funding-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
}

.funding-card__icon {
  display: grid;
  place-items: center;
  width: 62px;
  height: 62px;
  margin: 0 auto var(--space-3);
  border-radius: 50%;
  background: var(--teal-100);
  color: var(--teal-600);
  font-size: 1.4rem;
}

.funding-card h3 {
  font-size: var(--fs-lg);
}

.funding-card p {
  color: var(--ink-700);
  font-size: var(--fs-sm);
  margin: 0;
}

/* Steps */
.steps__title {
  font-size: var(--fs-h3);
  text-align: center;
  margin-bottom: var(--space-4);
}

.steps__list {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1rem, 2vw, 1.75rem);
  counter-reset: step;
}

.step {
  position: relative;
  padding-top: var(--space-2);
}

/* Connector line between step numbers */
.step::after {
  content: '';
  position: absolute;
  top: calc(var(--space-2) + 22px);
  left: calc(50% + 34px);
  width: calc(100% - 68px);
  height: 2px;
  background: repeating-linear-gradient(90deg, var(--line-strong) 0 8px, transparent 8px 16px);
}

.step:last-child::after {
  display: none;
}

.step__num {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: var(--space-2);
  border-radius: 50%;
  background: var(--plum-800);
  color: var(--white);
  font-weight: 800;
  font-size: var(--fs-md);
}

.step h4 {
  font-size: var(--fs-lg);
}

.step p {
  color: var(--ink-700);
  font-size: var(--fs-sm);
  margin: 0;
}


/* ==========================================================================
   11. FAQ ACCORDION
   ========================================================================== */
.accordion {
  display: grid;
  gap: .85rem;
}

.accordion__item {
  background: var(--off-white);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: border-color var(--transition), box-shadow var(--transition);
}

.accordion__item:has(.accordion__trigger[aria-expanded="true"]) {
  border-color: var(--teal-400);
  box-shadow: var(--shadow-sm);
}

.accordion__item h3 {
  margin: 0;
  font-size: inherit;
}

.accordion__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  padding: 1.2rem 1.4rem;
  background: transparent;
  border: 0;
  font: inherit;
  font-weight: 800;
  font-size: var(--fs-md);
  color: var(--plum-800);
  text-align: left;
  cursor: pointer;
}

.accordion__trigger:hover {
  color: var(--teal-600);
}

.accordion__chevron {
  color: var(--teal-600);
  flex-shrink: 0;
  transition: transform var(--transition);
}

.accordion__trigger[aria-expanded="true"] .accordion__chevron {
  transform: rotate(180deg);
}

/* Height animation without a magic max-height: the panel is a one-row grid that
   transitions 0fr → 1fr, so it animates to the content's real height. The
   padding sits on the <p> rather than the panel, or it would still take up
   space while collapsed. `visibility` keeps collapsed copy out of the a11y tree
   and out of tab order, and transitions in step with the height. */
.accordion__panel {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  /* Side padding is constant; the bottom padding animates with the height.
     It has to live here rather than on the child — padding on a grid item
     still contributes to the track's minimum size, so a padded child would
     leave a ~21px strip showing while "collapsed". */
  padding: 0 1.4rem;
  padding-bottom: 0;
  color: var(--ink-700);
  transition: grid-template-rows var(--transition), visibility var(--transition),
    padding-bottom var(--transition);
}

/* overflow + min-height:0 zero out the item's automatic minimum size, which is
   what lets the 0fr track actually reach 0. */
.accordion__panel>* {
  overflow: hidden;
  min-height: 0;
  margin: 0;
}

.accordion__panel.is-open {
  grid-template-rows: 1fr;
  visibility: visible;
  padding-bottom: 1.3rem;
}

/* No-JS fallback — main.js strips the attribute and drives .is-open instead */
.accordion__panel[hidden] {
  display: none;
}


/* ==========================================================================
   12. CONTACT & FORM
   ========================================================================== */
.contact__grid {
  display: grid;
  grid-template-columns: .8fr 1.2fr;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: start;
}

/* Sidebar */
.contact__aside {
  background: var(--plum-800);
  color: #E1D6F0;
  border-radius: var(--r-lg);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  box-shadow: var(--shadow-md);
}

.contact__aside-title {
  color: var(--white);
  font-size: var(--fs-h3);
  margin-bottom: var(--space-3);
}

.contact-item {
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: .8rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, .12);
  color: #E1D6F0;
  text-decoration: none;
}

.contact-item:last-of-type {
  border-bottom: 0;
}

.contact-item:hover {
  color: var(--white);
}

.contact-item__icon {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  border-radius: 12px;
  background: rgba(18, 180, 184, .2);
  color: var(--teal-400);
}

.contact-item strong {
  display: block;
  color: var(--white);
  font-size: var(--fs-sm);
}

.contact-item span span {
  font-size: var(--fs-sm);
}

/* The email is one unbreakable token, and a flex item defaults to
   min-width:auto — so in a narrow card it refused to shrink and ran out under
   whatever sat beside it. Let the text column shrink, and let the address wrap
   mid-word as a last resort rather than spill. */
.contact-item>span:last-child {
  min-width: 0;
}

.contact-item span span {
  overflow-wrap: anywhere;
}

.contact__note {
  display: flex;
  gap: .7rem;
  align-items: flex-start;
  margin-top: var(--space-3);
  padding: .9rem 1rem;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, .07);
  font-size: var(--fs-sm);
}

.contact__note i {
  color: var(--teal-400);
  margin-top: .3rem;
}

.contact__note p {
  margin: 0;
}

/* Form shell */
.contact__form-wrap {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(1.5rem, 3vw, 2.5rem);
  box-shadow: var(--shadow-sm);
}

.form__intro {
  font-size: var(--fs-sm);
  color: var(--ink-500);
  margin-bottom: var(--space-3);
}

.req {
  color: var(--danger);
  font-weight: 800;
}

.field {
  margin-bottom: var(--space-3);
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

.field label,
.fieldset legend {
  display: block;
  margin-bottom: .4rem;
  font-weight: 700;
  font-size: var(--fs-sm);
  color: var(--plum-800);
}

input[type="text"],
input[type="email"],
input[type="tel"],
select,
textarea {
  width: 100%;
  padding: .85rem 1rem;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--ink-900);
  background: var(--white);
  border: 2px solid var(--line-strong);
  border-radius: var(--r-md);
  transition: border-color var(--transition), box-shadow var(--transition);
}

textarea {
  resize: vertical;
  min-height: 120px;
}

input:hover,
select:hover,
textarea:hover {
  border-color: var(--ink-500);
}

input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--teal-500);
  box-shadow: 0 0 0 4px rgba(0, 144, 156, .22);
}

::placeholder {
  color: var(--ink-500);
  opacity: 1;
}

/* Native select arrow replaced with an inline SVG chevron */
select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234A3D57' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 18px;
  padding-right: 2.8rem;
}

/* Validation states */
.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea {
  border-color: var(--danger);
  background: var(--danger-bg);
}

.field.is-invalid input:focus,
.field.is-invalid select:focus,
.field.is-invalid textarea:focus {
  box-shadow: 0 0 0 4px rgba(179, 38, 30, .16);
}

.field.is-valid input,
.field.is-valid select {
  border-color: var(--teal-500);
}

.field__hint {
  margin: .35rem 0 0;
  font-size: var(--fs-xs);
  color: var(--ink-500);
}

.field__error {
  margin: 0;
  max-height: 0;
  overflow: hidden;
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--danger);
  transition: max-height var(--transition), margin var(--transition);
}

.field.is-invalid .field__error {
  max-height: 4rem;
  margin-top: .35rem;
}

.field__error::before {
  content: '\26A0';
  /* warning sign */
  margin-right: .35rem;
}

/* Fieldset / checkbox grid */
.fieldset {
  border: 0;
  padding: 0;
  margin-inline: 0;
}

.fieldset legend {
  padding: 0;
}

.checkbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: .6rem;
}

.checkbox {
  display: flex;
  align-items: flex-start;
  gap: .7rem;
  padding: .75rem .9rem;
  border: 2px solid var(--line);
  border-radius: var(--r-md);
  background: var(--off-white);
  font-weight: 600;
  font-size: var(--fs-sm);
  color: var(--ink-900);
  cursor: pointer;
  margin-bottom: 0;
  transition: border-color var(--transition), background var(--transition);
}

.checkbox:hover {
  border-color: var(--teal-400);
}

.checkbox:has(input:checked) {
  border-color: var(--teal-500);
  background: var(--teal-050);
}

.checkbox:has(input:focus-visible) {
  outline: 3px solid var(--teal-500);
  outline-offset: 2px;
}

.checkbox input[type="checkbox"] {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  margin: .12rem 0 0;
  accent-color: var(--teal-600);
  cursor: pointer;
}

.checkbox--consent {
  background: var(--white);
  align-items: flex-start;
}

.fieldset.is-invalid .checkbox-grid {
  outline: 2px solid var(--danger);
  outline-offset: 6px;
  border-radius: var(--r-md);
}

.form__status {
  margin: var(--space-3) 0 0;
  font-size: var(--fs-sm);
  font-weight: 700;
  text-align: center;
  color: var(--danger);
}

.form__status:empty {
  margin: 0;
}

.form__status.is-success {
  color: var(--success);
}


/* ==========================================================================
   14. BACK-TO-TOP, MODAL, TOASTS
   ========================================================================== */
.to-top {
  position: fixed;
  right: clamp(1rem, 3vw, 2rem);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: 90;
  display: grid;
  place-items: center;
  width: 50px;
  height: 50px;
  border: 0;
  border-radius: 50%;
  background: var(--plum-800);
  color: var(--white);
  font-size: 1.05rem;
  cursor: pointer;
  box-shadow: var(--shadow-lg);
  /* Parks off-screen-ish and inert until main.js adds .is-visible past 500px,
     so it fades and lifts in rather than snapping into existence. */
  opacity: 0;
  transform: translateY(12px) scale(.85);
  pointer-events: none;
  transition: background var(--transition), transform var(--transition), opacity var(--transition);
}

.to-top[hidden] {
  display: none;
}

/* no-JS fallback; main.js removes it */
.to-top.is-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.to-top.is-visible:hover {
  background: var(--teal-600);
  transform: translateY(-3px);
}

/* Modal */
.modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: var(--gutter);
}

.modal[hidden] {
  display: none;
}

.modal__overlay {
  position: absolute;
  inset: 0;
  background: rgba(38, 9, 63, .62);
  backdrop-filter: blur(3px);
  animation: fade-in 200ms ease both;
}

.modal__dialog {
  position: relative;
  width: min(100%, 520px);
  max-height: 88vh;
  overflow-y: auto;
  background: var(--white);
  border-radius: var(--r-xl);
  padding: clamp(1.75rem, 4vw, 2.75rem);
  text-align: center;
  box-shadow: var(--shadow-lg);
  animation: pop-in 260ms cubic-bezier(.2, .9, .3, 1.2) both;
}

.modal__icon {
  display: grid;
  place-items: center;
  width: 74px;
  height: 74px;
  margin: 0 auto var(--space-3);
  border-radius: 50%;
  background: var(--success-bg);
  color: var(--success);
  font-size: 1.9rem;
}

.modal__title {
  font-size: var(--fs-h3);
}

.modal__desc {
  color: var(--ink-700);
}

.modal__summary {
  margin: var(--space-3) 0;
  padding: 1rem 1.15rem;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--off-white);
  text-align: left;
  font-size: var(--fs-sm);
}

.modal__summary:empty {
  display: none;
}

.modal__summary dl {
  margin: 0;
  display: grid;
  gap: .5rem;
}

.modal__summary dt {
  font-weight: 800;
  color: var(--plum-800);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: .05em;
}

.modal__summary dd {
  margin: 0 0 .35rem;
  color: var(--ink-700);
}

.modal__summary dd:last-child {
  margin-bottom: 0;
}

/* Toasts */
.toast-stack {
  position: fixed;
  right: clamp(1rem, 3vw, 2rem);
  top: clamp(1rem, 3vw, 2rem);
  z-index: 210;
  display: grid;
  gap: .6rem;
  width: min(340px, calc(100vw - 2rem));
  pointer-events: none;
}

.toast {
  display: flex;
  gap: .7rem;
  align-items: flex-start;
  padding: .9rem 1.1rem;
  border-radius: var(--r-md);
  border-left: 5px solid var(--teal-500);
  background: var(--white);
  color: var(--ink-900);
  font-size: var(--fs-sm);
  font-weight: 600;
  box-shadow: var(--shadow-lg);
  animation: slide-in 260ms ease both;
  pointer-events: auto;
}

.toast.is-leaving {
  animation: slide-out 220ms ease both;
}

.toast--error {
  border-left-color: var(--danger);
}

.toast--error i {
  color: var(--danger);
}

.toast--success {
  border-left-color: var(--success);
}

.toast--success i {
  color: var(--success);
}

.toast i {
  margin-top: .2rem;
  flex-shrink: 0;
}


/* ==========================================================================
   15. LEGAL / INNER PAGES
   ========================================================================== */
.page-hero {
  background: linear-gradient(140deg, var(--plum-800), var(--teal-600));
  color: var(--white);
  padding-block: clamp(2.75rem, 6vw, 4.5rem);
}

.page-hero h1 {
  color: var(--white);
  font-size: clamp(2rem, 3vw * var(--a11y-zoom, 1) + 1rem, 3rem);
}

.page-hero p {
  color: #DCE9EC;
  margin: 0;
  max-width: 60ch;
}

.page-hero .eyebrow {
  color: var(--teal-100);
}

.page-hero .eyebrow i {
  color: var(--teal-100);
}

.prose {
  max-width: var(--container-narrow);
}

.prose h2 {
  font-size: var(--fs-h3);
  margin-top: var(--space-5);
}

.prose h2:first-of-type {
  margin-top: 0;
}

.prose h3 {
  font-size: var(--fs-lg);
  margin-top: var(--space-4);
}

.prose p,
.prose li {
  color: var(--ink-700);
}

.prose ul,
.prose ol {
  padding-left: 1.4rem;
  margin-bottom: var(--space-3);
  display: grid;
  gap: .5rem;
}

.prose li::marker {
  color: var(--teal-600);
}

.prose .updated {
  display: inline-block;
  padding: .35rem .9rem;
  border-radius: var(--r-pill);
  background: var(--teal-100);
  color: var(--plum-700);
  font-size: var(--fs-xs);
  font-weight: 700;
  margin-bottom: var(--space-4);
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin-top: var(--space-5);
  font-weight: 800;
  text-decoration: none;
}


/* ==========================================================================
   16. SERVICE PAGES
   ========================================================================== */

/* ---- Breadcrumb ---------------------------------------------------------- */
.breadcrumb {
  padding-block: var(--space-2);
  background: var(--white);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-xs);
}

.breadcrumb ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem .55rem;
}

.breadcrumb li {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  color: var(--ink-500);
}

.breadcrumb li+li::before {
  content: '\f105';
  /* chevron-right */
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  color: var(--line-strong);
}

.breadcrumb a {
  color: var(--ink-700);
  text-decoration: none;
  font-weight: 700;
}

.breadcrumb a:hover {
  color: var(--teal-600);
  text-decoration: underline;
}

.breadcrumb [aria-current="page"] {
  color: var(--plum-800);
  font-weight: 700;
}

/* ---- Service page hero --------------------------------------------------- */
.page-hero--service {
  position: relative;
  overflow: hidden;
  padding-block: clamp(2.5rem, 5vw, 4rem);
}

/* Soft radial wash so the flat gradient doesn't read as a solid slab */
.page-hero--service::after {
  content: '';
  position: absolute;
  inset: -40% -10% auto auto;
  width: 34rem;
  height: 34rem;
  background: radial-gradient(circle, rgba(255, 255, 255, .16) 0%, rgba(255, 255, 255, 0) 65%);
  pointer-events: none;
}

.page-hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: clamp(1.1rem, 3vw, 2rem);
}

.page-hero__icon {
  display: grid;
  place-items: center;
  width: 82px;
  height: 82px;
  border-radius: 24px;
  background: rgba(255, 255, 255, .14);
  border: 1px solid rgba(255, 255, 255, .28);
  color: var(--white);
  font-size: 2rem;
}

.page-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

/* Outlined button for use on the dark hero */
.btn--outline-light {
  background: transparent;
  color: var(--white);
  border-color: rgba(255, 255, 255, .55);
}

.btn--outline-light:hover {
  background: rgba(255, 255, 255, .12);
  border-color: var(--white);
  color: var(--white);
}

/* Facts strip under the hero copy */
.page-hero__facts {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .6rem 1.5rem;
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid rgba(255, 255, 255, .22);
}

.page-hero__facts li {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-weight: 700;
  font-size: var(--fs-sm);
  color: #E6F2F4;
}

.page-hero__facts i {
  color: var(--teal-100);
}

/* ---- Two-column split (copy beside a card) ------------------------------- */
.split {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}

.split__body>h2 {
  font-size: var(--fs-h2);
}

.split__body p {
  color: var(--ink-700);
}

.split__subhead {
  font-size: var(--fs-lg);
  margin-top: var(--space-4);
}

.split--reverse .split__media {
  order: -1;
}

/* Photo above, quote below, with room for the frame's offset block */
.split__media {
  display: grid;
  align-content: start;
}

.quote--under {
  margin-top: clamp(3rem, 5vw, 4rem);
}

/* Quote / lived-experience panel */
.quote {
  position: relative;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  border-radius: var(--r-lg);
  background: linear-gradient(140deg, var(--plum-800), var(--teal-600));
  color: #E9F4F6;
  box-shadow: var(--shadow-md);
}

.quote i.quote__mark {
  font-size: 1.75rem;
  color: rgba(255, 255, 255, .35);
  margin-bottom: var(--space-2);
  display: block;
}

.quote p {
  font-size: var(--fs-md);
  margin-bottom: var(--space-3);
}

.quote cite {
  font-style: normal;
  font-weight: 800;
  color: var(--white);
  font-size: var(--fs-sm);
}

/* ---- Included-in-this-service grid --------------------------------------- */
.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}

.feature {
  display: flex;
  gap: 1rem;
  padding: 1.35rem 1.4rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}

.feature:hover {
  transform: translateY(-4px);
  border-color: var(--teal-400);
  box-shadow: var(--shadow-md);
}

.feature__icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: 13px;
  background: var(--teal-050);
  color: var(--teal-600);
  font-size: 1.05rem;
}

.feature h3 {
  font-size: var(--fs-lg);
  margin-bottom: .25rem;
}

.feature p {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--ink-700);
}

.section--tint .feature {
  background: var(--off-white);
}

/* ---- Closing CTA band ---------------------------------------------------- */
.cta-band {
  background: linear-gradient(140deg, var(--plum-800) 0%, var(--plum-700) 45%, var(--teal-600) 100%);
  color: #DDEAEE;
  padding-block: clamp(2.75rem, 6vw, 4.25rem);
}

.cta-band__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.cta-band h2 {
  color: var(--white);
  font-size: var(--fs-h2);
  max-width: 20ch;
}

.cta-band p {
  max-width: 46ch;
  margin: 0;
}

.cta-band__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* Small print row of trust markers */
.trust-row {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .75rem 2rem;
  margin-top: var(--space-4);
}

.trust-row li {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-weight: 700;
  font-size: var(--fs-sm);
  color: var(--ink-700);
}

.trust-row i {
  color: var(--teal-600);
}


/* ==========================================================================
   16b. EDITORIAL LAYER — photography, bento, asymmetric heads
     The pieces that stop every section reading "centred heading + card grid".
   ========================================================================== */

/* ---- Photography --------------------------------------------------------- */
.photo {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-xl);
  background: var(--teal-050);
  /* holds the space while the image loads */
}

.photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.photo--tall {
  aspect-ratio: 4 / 5;
}

.photo--wide {
  aspect-ratio: 3 / 2;
}

.photo--pano {
  aspect-ratio: 21 / 9;
}

/* A plum block offset behind the image — the signature editorial move, and
   what gives the photo somewhere to sit instead of floating on white. */
.photo-frame {
  position: relative;
  isolation: isolate;
}

.photo-frame::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 1.75rem -1.75rem -1.75rem 1.75rem;
  border-radius: var(--r-xl);
  /* Solid brand block, not a wash — at low opacity it read as a stray shadow
     rather than a deliberate offset. */
  background: var(--teal-100);
  border: 1px solid var(--teal-400);
}

.photo-frame--right::before {
  inset: 1.75rem 1.75rem -1.75rem -1.75rem;
}

/* Warms the stock photography toward the brand without a duotone filter,
   which would crush skin tones. A light plum veil, multiply-blended. */
.photo--warm::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(150deg, rgba(72, 24, 120, .20), rgba(0, 144, 156, .12));
  mix-blend-mode: multiply;
  pointer-events: none;
}

/* Caption pinned into the corner of a photo */
.photo__tag {
  position: absolute;
  left: 1rem;
  bottom: 1rem;
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  padding: .6rem 1rem;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(6px);
  color: var(--plum-800);
  font-size: var(--fs-xs);
  font-weight: 800;
  box-shadow: var(--shadow-md);
}

.photo__tag i {
  color: var(--teal-600);
}

/* ---- Asymmetric section heads -------------------------------------------- */
.section__head--left {
  margin-inline: 0;
  margin-bottom: clamp(1.75rem, 3vw, 2.75rem);
  text-align: left;
  max-width: 46ch;
}

/* Head on the left, supporting copy or a CTA on the right */
.section__head--split {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  align-items: end;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  max-width: none;
  margin-inline: 0;
  text-align: left;
}

.section__head--split .section__lede {
  margin: 0;
}

/* Short rule under a heading — cheap, and it reads as considered */
.rule {
  width: 64px;
  height: 4px;
  margin: var(--space-3) 0 0;
  border: 0;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--plum-700), var(--teal-500));
}

.section__head--left .rule,
.section__head--split .rule {
  margin-top: var(--space-3);
}

/* ---- Bento grid ----------------------------------------------------------
   Six columns so tiles can be halves, thirds and two-thirds. Tile sizes vary
   deliberately: equal cards in a 3-up grid is what made the old page read flat. */
.bento {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(1rem, 2vw, 1.5rem);
}

.bento>* {
  grid-column: span 3;
}

/* default: half width */
.bento__feature {
  grid-column: span 4;
  grid-row: span 2;
}

.bento__sm {
  grid-column: span 2;
}

.bento__full {
  grid-column: span 6;
}

/* The feature tile carries the photo and stacks its copy underneath. The media
   grows to absorb the tile's spare height — with a fixed aspect ratio the
   two-row tile left a dead gap above the tags. */
.bento__feature .service-card__media {
  margin: calc(-1 * clamp(1.5rem, 2.5vw, 2rem)) calc(-1 * clamp(1.5rem, 2.5vw, 2rem)) var(--space-3);
  border-radius: 0;
  flex: 1 1 auto;
  min-height: 250px;
}

.service-card__media {
  overflow: hidden;
}

.service-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 600ms cubic-bezier(.4, 0, .2, 1);
}

.service-card:hover .service-card__media img {
  transform: scale(1.04);
}

/* ---- Full-bleed photo band ------------------------------------------------
   One per page at most. Breaks the rhythm of stacked light sections. */
.photo-band {
  position: relative;
  min-height: clamp(320px, 42vw, 460px);
  display: grid;
  align-items: center;
  overflow: hidden;
  isolation: isolate;
}

.photo-band__img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-band::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  /* Solid enough on the left to carry white text at AA, clearing to show the
     photograph on the right. */
  background: linear-gradient(90deg,
      rgba(38, 9, 63, .93) 0%,
      rgba(38, 9, 63, .86) 38%,
      rgba(38, 9, 63, .45) 70%,
      rgba(38, 9, 63, .25) 100%);
}

/* Constrain the children, not the .container itself — putting max-width on the
   container makes its `margin-inline: auto` centre the whole block instead of
   letting it start at the page gutter like every other section. */
.photo-band__inner {
  padding-block: var(--space-6);
}

.photo-band__inner>* {
  max-width: 46ch;
}

.photo-band h2 {
  color: var(--white);
  font-size: var(--fs-h2);
}

.photo-band p {
  color: #E4DAF0;
  margin-bottom: 0;
}

.photo-band .eyebrow {
  color: var(--teal-100);
}

.photo-band .eyebrow i {
  color: var(--teal-100);
}

.photo-band .btn {
  margin-top: var(--space-4);
}

/* ---- Editorial hero (home) ------------------------------------------------
   The photo fills the column; the two cards break its edges so the composition
   has depth instead of sitting in a neat rectangle. */
.hero__photo {
  display: block;
  min-height: 0;
  padding-inline: 1.5rem;
  /* room for the cards to hang outside the photo */
}

.hero__photo .photo {
  box-shadow: var(--shadow-lg);
}

.hero__photo .hero__card--main {
  position: absolute;
  z-index: 2;
  left: 0;
  bottom: 2rem;
  max-width: 296px;
}

.hero__photo .hero__card--one {
  z-index: 2;
  top: 2rem;
  right: 0;
  left: auto;
}


/* ==========================================================================
   17. MOBILE ACTION BAR
     Phone-only sticky footer with the two actions people actually came for.
     Hidden above 620px, where the header CTA and topbar already cover it.
   ========================================================================== */
.mobile-bar {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 95;
  gap: .6rem;
  padding: .6rem .8rem calc(.6rem + env(safe-area-inset-bottom, 0px));
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--line);
  box-shadow: 0 -4px 18px rgba(38, 9, 63, .1);
}

.mobile-bar .btn {
  flex: 1;
  padding: .8rem 1rem;
  font-size: var(--fs-sm);
}


/* ==========================================================================
   18. ANIMATIONS & REDUCED MOTION
   ========================================================================== */
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes float {

  0%,
  100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-12px);
  }
}

@keyframes morph {

  0%,
  100% {
    border-radius: 46% 54% 38% 62% / 52% 42% 58% 48%;
  }

  50% {
    border-radius: 58% 42% 56% 44% / 40% 58% 42% 60%;
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@keyframes pop-in {
  from {
    opacity: 0;
    transform: translateY(18px) scale(.96);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes slide-in {
  from {
    opacity: 0;
    transform: translateX(28px);
  }

  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes slide-out {
  from {
    opacity: 1;
    transform: translateX(0);
  }

  to {
    opacity: 0;
    transform: translateX(28px);
  }
}

/* Scroll-reveal — elements start hidden, JS adds .is-visible.
   Variants change only the starting transform, so `.is-visible` resetting to
   `none` lands them all in the same place. main.js assigns one per element
   type (see revealGroups) so a page doesn't animate in all one way. */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 600ms ease, transform 600ms ease;
}

.reveal--zoom {
  transform: translateY(14px) scale(.955);
}

.reveal--left {
  transform: translateX(-30px);
}

.reveal--right {
  transform: translateX(30px);
}

.reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Page-load entrance for the two hero types. `both` fill matters: under
   prefers-reduced-motion the duration collapses to ~0 and the end state is
   what sticks, so the content is simply there. */
@keyframes enter-up {
  from {
    opacity: 0;
    transform: translateY(20px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes enter-pop {
  from {
    opacity: 0;
    transform: scale(.82);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.hero__content>*,
.page-hero__body>* {
  animation: enter-up 640ms cubic-bezier(.4, 0, .2, 1) both;
}

.hero__content>*:nth-child(1),
.page-hero__body>*:nth-child(1) {
  animation-delay: 40ms;
}

.hero__content>*:nth-child(2),
.page-hero__body>*:nth-child(2) {
  animation-delay: 120ms;
}

.hero__content>*:nth-child(3),
.page-hero__body>*:nth-child(3) {
  animation-delay: 200ms;
}

.hero__content>*:nth-child(4),
.page-hero__body>*:nth-child(4) {
  animation-delay: 280ms;
}

.hero__content>*:nth-child(5),
.page-hero__body>*:nth-child(5) {
  animation-delay: 360ms;
}

.page-hero__icon {
  animation: enter-pop 520ms cubic-bezier(.2, .9, .3, 1.2) both;
}

.hero__visual {
  animation: enter-pop 800ms cubic-bezier(.2, .9, .3, 1.1) both 120ms;
}

/* Respect users who prefer less motion */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }

  .reveal {
    opacity: 1;
    transform: none;
  }

  .btn:hover,
  .highlight:hover,
  .service-card:hover,
  .funding-card:hover,
  .feature:hover,
  .to-top.is-visible:hover {
    transform: none;
  }

  /* Hover transforms off; colour/shadow feedback stays, so nothing loses its
     affordance — only the movement goes. */
  .service-card:hover .service-card__more i,
  .service-card:hover .service-card__icon,
  .feature:hover .feature__icon,
  .highlight:hover .highlight__icon,
  .funding-card:hover .funding-card__icon,
  .contact-item:hover .contact-item__icon,
  .step:hover .step__num,
  /* Entrances and staggers land instantly in their end state */
  .hero__content>*,
  .page-hero__body>*,
  .page-hero__icon,
  .hero__visual {
    animation: none;
    opacity: 1;
    transform: none;
  }

  .nav__dropdown li,
  .nav__menu .nav__list>li,
  .nav__menu .nav__cta {
    opacity: 1;
    transform: none;
    transition-delay: 0s !important;
  }

  .nav__link::after {
    transition: none;
  }
}

/* Honour OS-level high-contrast preferences */
@media (prefers-contrast: more) {
  :root {
    --ink-700: #332A3D;
    --ink-500: #4E4359;
    --line: #AD9FBC;
    --line-strong: #877598;
  }
}


/* ---- Hover micro-interactions --------------------------------------------
   The card lift already does the heavy lifting; these give the icon inside it
   a little life so the whole tile feels like one object responding. */
.service-card__icon,
.feature__icon,
.highlight__icon,
.funding-card__icon,
.contact-item__icon {
  transition: transform var(--transition), background var(--transition);
}

.service-card:hover .service-card__icon {
  transform: scale(1.07) rotate(-4deg);
}

.feature:hover .feature__icon {
  transform: scale(1.08);
}

.highlight:hover .highlight__icon {
  transform: scale(1.08) rotate(-4deg);
}

.funding-card:hover .funding-card__icon {
  transform: scale(1.07);
}

.contact-item:hover .contact-item__icon {
  transform: scale(1.07);
}

/* Tags tint on card hover instead of sitting inert */
.tag-list li {
  transition: background var(--transition), color var(--transition);
}

.service-card:hover .tag-list li {
  background: var(--teal-050);
}

/* Step markers get a ring on section hover-in */
.step__num {
  transition: transform var(--transition), box-shadow var(--transition);
}

.step:hover .step__num {
  transform: scale(1.08);
  box-shadow: 0 0 0 6px var(--teal-050);
}


/* ==========================================================================
   19. RESPONSIVE BREAKPOINTS
   ========================================================================== */

/* Large desktop → small desktop */
/* Tablet landscape */
@media (max-width: 960px) {
  .split {
    grid-template-columns: 1fr;
  }

  .split--reverse .split__media {
    order: 0;
  }

  .cta-band__inner {
    flex-direction: column;
    align-items: flex-start;
  }

  .cta-band h2 {
    max-width: none;
  }

  .section__head--split {
    grid-template-columns: 1fr;
    align-items: start;
  }

  /* Bento collapses to halves, feature keeps its prominence */
  .bento__feature {
    grid-column: span 6;
    grid-row: auto;
  }

  .bento__sm {
    grid-column: span 3;
  }

  /* The gradient has to cover the whole frame once the text sits over the photo */
  .photo-band::after {
    background: linear-gradient(180deg, rgba(38, 9, 63, .82) 0%, rgba(38, 9, 63, .93) 100%);
  }

  .photo-band__inner {
    max-width: none;
  }

  .hero__inner {
    grid-template-columns: 1fr;
  }

  .hero__subtitle {
    max-width: 52ch;
  }

  .hero__visual {
    order: -1;
    min-height: 300px;
  }

  .hero__card--one {
    top: 2%;
  }

  .hero__card--two {
    bottom: 2%;
  }

  .about__grid {
    grid-template-columns: 1fr;
  }

  .contact__grid {
    grid-template-columns: 1fr;
  }

  .steps__list {
    grid-template-columns: repeat(2, 1fr);
  }

  .step:nth-child(2)::after {
    display: none;
  }

  .stats__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-4) var(--space-3);
  }

  .stat:nth-child(odd) {
    border-left: 0;
  }
}

/* Tablet portrait & below — nav collapses to a drawer */
@media (max-width: 860px) {
  .topbar__item--muted {
    display: none;
  }

  .topbar__inner {
    justify-content: center;
  }

  .nav__toggle {
    display: flex;
  }

  .nav__menu {
    position: fixed;
    inset: 0 0 0 auto;
    width: min(88vw, 360px);
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: var(--space-3);
    padding: 6rem var(--space-4) var(--space-4);
    background: var(--white);
    border-left: 1px solid var(--line);
    box-shadow: var(--shadow-lg);
    transform: translateX(100%);
    visibility: hidden;
    transition: transform var(--transition), visibility var(--transition);
    overflow-y: auto;
    /* Stop a flick inside the drawer from chaining into the page behind it. */
    overscroll-behavior: contain;
    z-index: 110;
  }

  .nav__menu.is-open {
    transform: translateX(0);
    visibility: visible;
  }

  /* Drawer contents slide in a beat behind the panel itself */
  .nav__menu .nav__list>li,
  .nav__menu .nav__cta {
    opacity: 0;
    transform: translateX(20px);
    transition: opacity 260ms ease, transform 260ms ease;
  }

  .nav__menu.is-open .nav__list>li,
  .nav__menu.is-open .nav__cta {
    opacity: 1;
    transform: none;
  }

  .nav__menu.is-open .nav__list>li:nth-child(1) {
    transition-delay: 90ms;
  }

  .nav__menu.is-open .nav__list>li:nth-child(2) {
    transition-delay: 130ms;
  }

  .nav__menu.is-open .nav__list>li:nth-child(3) {
    transition-delay: 170ms;
  }

  .nav__menu.is-open .nav__list>li:nth-child(4) {
    transition-delay: 210ms;
  }

  .nav__menu.is-open .nav__list>li:nth-child(5) {
    transition-delay: 250ms;
  }

  .nav__menu.is-open .nav__cta {
    transition-delay: 290ms;
  }

  .nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: .25rem;
  }

  .nav__list>li {
    display: block;
  }

  .nav__link {
    padding: .9rem 1rem;
    font-size: var(--fs-md);
    border-bottom: 1px solid var(--line);
    border-radius: 0;
  }

  .nav__link.is-active::after {
    display: none;
  }

  .nav__link.is-active {
    background: var(--teal-050);
  }

  .nav__cta {
    width: 100%;
    margin-top: var(--space-2);
  }

  /* Services dropdown becomes an inline, collapsible sub-list in the drawer.
     Selector matches `.nav__list > li` above or that rule's display:block wins
     and the chevron drops onto its own line. */
  .nav__list>li.nav__item--has-menu {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    border-bottom: 1px solid var(--line);
  }

  .nav__item--has-menu .nav__link {
    border-bottom: 0;
  }

  /* Tint the whole row, not just the link's cell, when it's the current page */
  .nav__list>li.nav__item--has-menu:has(.nav__link.is-active) {
    background: var(--teal-050);
  }

  .nav__submenu-toggle {
    width: 44px;
    height: 44px;
    font-size: 1rem;
    border-left: 1px solid var(--line);
    border-radius: 0;
  }

  .nav__dropdown {
    grid-column: 1 / -1;
    position: static;
    width: auto;
    padding: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: var(--teal-050);
    display: none;
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  .nav__item--has-menu.is-open .nav__dropdown {
    display: block;
    padding: .4rem;
  }

  .nav__dropdown a {
    padding: .75rem .9rem;
  }

  .nav__dropdown a small {
    display: none;
  }

  .nav__dropdown li:last-child a {
    border-top-color: var(--line-strong);
  }

  /* Dim the page behind the open drawer.
     `.site-header` is sticky with a z-index, so it opens its own stacking
     context: the drawer's z-index below only orders it *within* the header,
     not against the rest of the page. main.js therefore appends the backdrop
     inside the header too — appended to <body> it would out-paint the header
     (105 > 100) and cover the drawer, swallowing every tap. */
  .nav-backdrop {
    position: fixed;
    inset: 0;
    z-index: 105;
    background: rgba(38, 9, 63, .5);
    animation: fade-in 200ms ease both;
    /* iOS Safari scrolls the page even with `overflow: hidden` on <body>;
       refusing touch gestures here is what actually holds it still. */
    touch-action: none;
  }

  /* Keep the toggle above the drawer so it can close it */
  .nav__toggle {
    position: relative;
    z-index: 120;
  }
}

/* Mobile */
@media (max-width: 620px) {
  :root {
    --lh-base: 1.65;
  }

  .field-row {
    grid-template-columns: 1fr;
  }

  .steps__list {
    grid-template-columns: 1fr;
  }

  .step::after {
    display: none;
  }

  .about__highlights {
    grid-template-columns: 1fr;
  }

  .hero__actions .btn {
    width: 100%;
  }

  .topbar {
    font-size: var(--fs-xs);
  }

  .topbar__inner {
    gap: .25rem 1rem;
  }

  /* Shrink the lockup so it clears the hamburger on narrow screens */
  .brand__logo {
    height: 62px;
  }

  .service-card--cta .btn {
    align-self: stretch;
  }

  .toast-stack {
    left: 1rem;
    right: 1rem;
    width: auto;
  }

  /* Page hero stacks; icon shrinks so the heading keeps its line length */
  .page-hero__inner {
    grid-template-columns: 1fr;
  }

  .page-hero__icon {
    width: 62px;
    height: 62px;
    font-size: 1.5rem;
    border-radius: 18px;
  }

  .page-hero__actions .btn {
    width: 100%;
  }

  .cta-band__actions {
    width: 100%;
  }

  .cta-band__actions .btn {
    width: 100%;
  }

  .feature {
    flex-direction: column;
    gap: .75rem;
  }

  /* Editorial layer stacks to one column */
  .bento>*,
  .bento__feature,
  .bento__sm {
    grid-column: span 6;
    grid-row: auto;
  }

  .photo-frame::before {
    inset: 1rem -1rem -1rem 1rem;
  }

  .photo-frame--right::before {
    inset: 1rem 1rem -1rem -1rem;
  }

  .photo--tall {
    aspect-ratio: 4 / 3;
  }

  /* Sticky call/referral bar — and everything that must clear it */
  .mobile-bar {
    display: flex;
  }

  body {
    padding-bottom: 4.75rem;
  }

  .to-top {
    bottom: 5.5rem;
    width: 44px;
    height: 44px;
  }
}

/* Very small phones */
@media (max-width: 400px) {
  .brand__logo {
    height: 54px;
  }

  .stats__grid {
    grid-template-columns: 1fr;
  }

  .stat {
    border-left: 0;
  }

  .hero__card--float {
    display: none;
  }
}


/* ==========================================================================
   20. PRINT
   ========================================================================== */
@media print {

  .site-header,
  .to-top,
  .sf__social,
  .sf__cta,
  .mobile-bar,
  .breadcrumb,
  .hero__visual,
  .modal,
  .toast-stack {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
    padding-bottom: 0;
  }

  .section {
    padding-block: 1.5rem;
  }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: .85em;
  }
}


/* ==========================================================================
   21. REDESIGN LAYER
     Appended overrides from the editorial redesign pass. Each block below is
     scoped to one component family and was written against the tokens above —
     nothing here introduces a dependency or changes behaviour.
   ========================================================================== */


/* ---------- HERO & PAGE HEADERS ---------- */

/* ==========================================================================
   21. HERO & PAGE-HEADER — EDITORIAL PASS
       Appended override block. Scope: .hero*, .page-hero*, .photo-band*,
       .stats/.stat only. Nothing outside those families is touched.

       The problem being solved: both hero types read as "text left, box right"
       with an evenly-weighted stack. This pass gives them a composition —
       one anchored ground per hero, a leading rule that starts the eyebrow,
       a bigger and tighter display line, a photo that sits on something, and
       trust markers set as columns instead of a wrapped sentence.

       No new @keyframes. The existing enter-up / enter-pop entrance is left
       exactly as it is, and nothing here sets `transform` on .hero__visual or
       .page-hero__icon, so the entrance cannot be fought.
   ========================================================================== */


/* ---- Shared: the eyebrow gets a leading rule ------------------------------
   One idiom used in all three hero-family headers so they read as a set.
   The rule is decorative only — the eyebrow text carries its own contrast
   (teal-600 on the hero ground 4.71:1 worst case; teal-100 on the page-hero
   ground 5.02:1 worst case). Scoped to hero contexts, never global. */
.hero__content>.eyebrow,
.page-hero__body>.eyebrow,
.photo-band__inner>.eyebrow {
  align-items: center;
  gap: .7rem;
  margin-bottom: var(--space-3);
  letter-spacing: .12em;
}

.hero__content>.eyebrow::before,
.page-hero__body>.eyebrow::before,
.photo-band__inner>.eyebrow::before {
  content: '';
  flex: 0 0 auto;
  width: 1.9rem;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  opacity: .55;
}


/* ==========================================================================
   HOME HERO
   ========================================================================== */

/* Two soft grounds instead of one: teal behind the photograph (top right),
   a faint plum wash under the copy (bottom left). It gives the composition a
   diagonal without adding a single visible edge.
   Lightest point reached = --white; darkest = plum-600 @10% over off-white.
   plum-800 heading 12.5:1 / 10.1:1 · ink-700 body 10.0:1 / 8.1:1 across that
   whole range — every value AA at body size. */
.hero {
  padding-block: clamp(3.25rem, 7.5vw, 6.5rem) clamp(3.75rem, 8vw, 7rem);
  background:
    radial-gradient(46rem 30rem at 94% -10%, var(--teal-100) 0%, rgba(210, 239, 242, 0) 60%),
    radial-gradient(38rem 26rem at -8% 104%, rgba(120, 60, 144, .10) 0%, rgba(120, 60, 144, 0) 62%),
    linear-gradient(180deg, var(--white) 0%, var(--off-white) 100%);
}

/* Asymmetry comes from the column ratio plus a small downward offset on the
   photo column — margin, not transform, so the enter-pop entrance is intact. */
.hero__inner {
  grid-template-columns: minmax(0, 1.06fr) minmax(0, .94fr);
  align-items: center;
  gap: clamp(2.25rem, 5.5vw, 5rem);
}

.hero__content {
  max-width: 36rem;
}

/* Display line: larger, tighter, and allowed to break where it wants. The
   old --fs-h1 ceiling (3.85rem) under-used a 34ch measure. */
.hero__title {
  font-size: clamp(2.35rem, 4.6vw * var(--a11y-zoom, 1) + .6rem, 4.2rem);
  line-height: 1.03;
  letter-spacing: -.028em;
  max-width: 18ch;
  margin-bottom: var(--space-4);
  text-wrap: balance;
}

/* The lede sits at a genuine reading measure and one clear step below the
   heading, so the stack reads eyebrow → statement → explanation → action. */
.hero__subtitle {
  font-size: clamp(1.12rem, .55vw * var(--a11y-zoom, 1) + 1rem, 1.32rem);
  line-height: 1.55;
  max-width: 38ch;
  margin-bottom: var(--space-5);
  text-wrap: pretty;
}

/* One hero action, unmistakably. The primary keeps --teal-600 (white text
   5.83:1) and gains a teal glow; the secondary keeps its transparent fill but
   swaps the near-invisible --line-strong edge (1.73:1 on white — well under
   the 3:1 required of a meaningful UI boundary) for --plum-600 at 7.37:1. */
.hero__actions {
  gap: .75rem;
  margin-bottom: var(--space-5);
}

.hero__actions .btn--primary {
  box-shadow: 0 10px 26px rgba(0, 112, 123, .22);
}

.hero__actions .btn--primary:hover {
  box-shadow: 0 14px 32px rgba(0, 112, 123, .30);
}

.hero__actions .btn--ghost {
  border-color: var(--plum-600);
}

/* Trust markers as three ruled columns rather than a wrapped run-on line.
   Hairline column rules, not boxes — depth by layering, per DESIGN.md.
   ink-700 label on the hero ground: 8.1:1 worst case. */
.hero__trust {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  margin-top: var(--space-1);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line-strong);
}

.hero__trust li {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  padding-inline: clamp(.7rem, 1.6vw, 1.2rem);
  border-left: 1px solid var(--line);
  font-size: var(--fs-sm);
  line-height: 1.35;
}

.hero__trust li:first-child {
  padding-left: 0;
  border-left: 0;
}

.hero__trust i {
  margin-top: .18em;
  flex-shrink: 0;
}


/* ---- The photograph and the cards that break its edges -------------------- */

/* The photo now sits on something. Reusing the established .photo-frame
   idiom (teal-100 block, teal-400 hairline) at hero scale, offset down and
   right so it peeks out on the two edges the cards do not occupy. */
.hero__photo {
  position: relative;
  isolation: isolate;
  min-height: 0;
  margin-top: clamp(0rem, 2vw, 1.75rem);
  padding-inline: 1.5rem;
}

.hero__photo::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 3rem -.9rem -1.6rem 30%;
  border-radius: var(--r-xl);
  background: var(--teal-100);
  border: 1px solid var(--teal-400);
}

/* Two stacked shadows, the lower one plum-tinted, so the image reads as
   lifted off the ground rather than cut out and pasted on. */
.hero__photo .photo {
  box-shadow:
    0 32px 64px rgba(38, 9, 63, .16),
    0 10px 22px rgba(38, 9, 63, .09);
}

/* Glassmorphism where it is actually earned — a translucent panel over a
   photograph. Opacity is set from the contrast floor, not from taste:
   at 94% white over a worst-case BLACK photo the panel resolves to L .869,
   giving plum-800 10.9:1 and ink-700 9.1:1; over a worst-case WHITE photo it
   is effectively white, 12.5:1 / 10.0:1. Both ends AA at body size. */
.hero__card {
  background: rgba(255, 255, 255, .94);
  border: 1px solid rgba(255, 255, 255, .75);
  border-radius: var(--r-lg);
  box-shadow:
    0 20px 44px rgba(38, 9, 63, .18),
    0 4px 12px rgba(38, 9, 63, .08);
}

/* Where backdrop-filter exists the panel can be more transparent and still
   clear AA: 84% white over black resolves to L .674 — plum-800 8.6:1,
   ink-700 6.9:1, teal-600 icon 4.0:1 (decorative, needs 3:1). */
@supports ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .hero__card {
    background: rgba(255, 255, 255, .84);
    -webkit-backdrop-filter: blur(16px) saturate(1.35);
    backdrop-filter: blur(16px) saturate(1.35);
  }
}

.hero__card--main {
  gap: 1.05rem;
  max-width: 320px;
  padding: 1.4rem 1.55rem;
}

.hero__photo .hero__card--main {
  left: 0;
  bottom: clamp(1.5rem, 4vw, 3rem);
  max-width: 310px;
}

.hero__avatar {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(0, 112, 123, .20);
}

/* The card title echoes the display serif of the h1 — that repetition is what
   makes the card feel authored rather than dropped in. */
.hero__card-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-md);
  line-height: 1.2;
  letter-spacing: -.01em;
  margin-bottom: .2rem;
}

.hero__card-text {
  font-size: var(--fs-sm);
  line-height: 1.45;
}

.hero__card--float {
  padding: .8rem 1.2rem;
  border-radius: var(--r-pill);
  font-size: var(--fs-sm);
}

.hero__photo .hero__card--one {
  top: clamp(1.25rem, 3.5vw, 2.5rem);
  right: 0;
  left: auto;
}


/* ==========================================================================
   STATS BAND
   ========================================================================== */

/* Was a flat plum slab with four centred blocks. Now a graded ground with the
   figures set left in the display serif — the band becomes a piece of the
   editorial system instead of a widget strip.
   Lightest colour the gradient reaches = --plum-700 (L .0566):
     .stat__num  --teal-400  3.87:1 — large text (≥35px), needs 3:1  ✓
     .stat__label #DACCEA    6.48:1 — body size, needs 4.5:1         ✓
   On the dominant plum-800/900 body of the band those rise to 4.92:1 / 8.23:1
   and 6.91:1 / 11.4:1. */
.stats {
  padding-block: clamp(2.5rem, 5vw, 4rem);
  background:
    radial-gradient(48rem 26rem at 84% -35%, var(--plum-700) 0%, rgba(94, 36, 144, 0) 68%),
    linear-gradient(180deg, var(--plum-800) 0%, var(--plum-900) 100%);
}

.stats__grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.75rem) 0;
  text-align: left;
}

.stat {
  padding-inline: clamp(1rem, 2.4vw, 2rem) .5rem;
  border-left: 1px solid rgba(255, 255, 255, .16);
}

.stat:first-child {
  padding-left: 0;
  border-left: 0;
}

.stat__num {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.2rem, 3.6vw * var(--a11y-zoom, 1), 3.2rem);
  line-height: 1.02;
  letter-spacing: -.025em;
  font-variant-numeric: lining-nums tabular-nums;
}

.stat__label {
  margin-top: .55rem;
  max-width: 20ch;
  font-size: var(--fs-xs);
  line-height: 1.45;
}


/* ==========================================================================
   PAGE HERO (legal pages) + SERVICE HERO
   ========================================================================== */

/* The gradient now lands on --teal-700 rather than --teal-600 and is anchored
   at plum-900. This is a contrast fix as much as a look: with the white
   radial wash sitting on top, the old teal-600 corner resolved to L .198 —
   #DCE9EC body copy there measured 3.41:1, i.e. it FAILED AA. Lightest point
   now (teal-700 under the reduced .10 wash, L .123):
     white h1        6.07:1  ✓
     #DCE9EC lede    4.89:1  ✓ (was 3.41:1)
     --teal-100 eyebrow 5.02:1 ✓
     #E6F2F4 facts   5.31:1  ✓
   As a side effect the out-of-scope .btn--outline-light edge rises from
   ~2.6:1 to 3.00:1 against that same worst-case point. */
.page-hero {
  background:
    linear-gradient(118deg,
      var(--plum-900) 0%,
      var(--plum-800) 42%,
      var(--teal-700) 100%);
  padding-block: clamp(3rem, 6.5vw, 5rem);
}

.page-hero h1 {
  font-size: clamp(2.15rem, 3.4vw * var(--a11y-zoom, 1) + .8rem, 3.4rem);
  line-height: 1.05;
  letter-spacing: -.025em;
  max-width: 20ch;
  margin-bottom: var(--space-3);
}

/* :not(.eyebrow) so the label above the heading keeps its own treatment */
.page-hero__body>p:not(.eyebrow) {
  font-size: var(--fs-md);
  line-height: 1.6;
  max-width: 54ch;
  text-wrap: pretty;
}

/* Wash pulled back to .10 and pushed further off-canvas — it should suggest
   light falling across the panel, not lift the corner out of contrast. */
.page-hero--service::after {
  inset: -55% -18% auto auto;
  width: 40rem;
  height: 40rem;
  background: radial-gradient(circle, rgba(255, 255, 255, .10) 0%, rgba(255, 255, 255, 0) 66%);
}

/* Icon | hairline | copy. The rule is what turns the icon from a floating
   badge into the first column of a masthead. */
.page-hero__inner {
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(1.25rem, 2.6vw, 2.25rem);
  align-items: start;
}

.page-hero__body {
  border-left: 1px solid rgba(255, 255, 255, .20);
  padding-left: clamp(1.25rem, 2.6vw, 2.25rem);
}

/* Glass tile. The white glyph inside carries the meaning at 12.5:1 on
   plum-800; the tile edge at 38% white measures 3.00:1 on that same ground. */
.page-hero__icon {
  width: 78px;
  height: 78px;
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .12);
  border: 1px solid rgba(255, 255, 255, .38);
  font-size: 1.85rem;
}

@supports ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .page-hero__icon {
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
  }
}

.page-hero__actions {
  gap: .75rem;
  margin-top: var(--space-5);
}

.page-hero__actions .btn--light {
  box-shadow: 0 10px 26px rgba(38, 9, 63, .30);
}

.page-hero__actions .btn--light:hover {
  box-shadow: 0 14px 32px rgba(38, 9, 63, .38);
}

/* Facts strip mirrors .hero__trust exactly, so the two hero types share a
   footer rhythm. Divider raised to 28% white so it survives the darker ground. */
.page-hero__facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(255, 255, 255, .28);
}

.page-hero__facts li {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  padding-inline: clamp(.7rem, 1.6vw, 1.2rem);
  border-left: 1px solid rgba(255, 255, 255, .18);
  line-height: 1.35;
}

.page-hero__facts li:first-child {
  padding-left: 0;
  border-left: 0;
}

.page-hero__facts i {
  margin-top: .18em;
  flex-shrink: 0;
}


/* ==========================================================================
   PHOTO BAND
   ========================================================================== */

/* Taller, and the scrim gains a vertical component so the top edge of the
   photograph stays open while the copy block sits on the densest part.
   Worst case = a pure white photograph under the .86 stop where the text
   ends (46ch ≈ 38% of the container): white h2 12.0:1, #E4DAF0 lede 8.9:1,
   --teal-100 eyebrow 9.9:1. All AA with room to spare. */
.photo-band {
  min-height: clamp(360px, 46vw, 520px);
}

.photo-band::after {
  background:
    linear-gradient(180deg, rgba(38, 9, 63, .30) 0%, rgba(38, 9, 63, 0) 45%),
    linear-gradient(90deg,
      rgba(38, 9, 63, .94) 0%,
      rgba(38, 9, 63, .88) 38%,
      rgba(38, 9, 63, .46) 70%,
      rgba(38, 9, 63, .24) 100%);
}

.photo-band__inner {
  padding-block: clamp(3rem, 6vw, 4.5rem);
}

.photo-band h2 {
  line-height: 1.08;
  letter-spacing: -.022em;
  max-width: 20ch;
  margin-bottom: var(--space-3);
}

.photo-band__inner>p:not(.eyebrow) {
  font-size: var(--fs-md);
  line-height: 1.6;
}

.photo-band .btn {
  margin-top: var(--space-5);
}


/* ==========================================================================
   REDUCED MOTION
     Nothing in this block introduces an animation, so there is nothing new to
     switch off. These rules are belt-and-braces: they pin the pre-existing
     hero decorations to their resting state rather than relying on the global
     `animation-duration: .01ms` collapse, and guarantee the new glass panels
     and grounds never move.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {

  .hero__card--float,
  .hero__card--one,
  .hero__card--two,
  .hero__blob,
  .hero__photo::before,
  .page-hero--service::after {
    animation: none !important;
    transform: none !important;
  }

  .hero__actions .btn--primary:hover,
  .page-hero__actions .btn--light:hover {
    transform: none;
  }
}


/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

/* Small desktop — pull the columns in before the type has to shrink */
@media (max-width: 1080px) {
  .hero__inner {
    gap: clamp(1.75rem, 4vw, 3rem);
  }

  .hero__photo {
    padding-inline: 1.1rem;
  }

  .hero__photo::before {
    inset: 2.5rem -.7rem -1.3rem 34%;
  }

  .hero__photo .hero__card--main {
    max-width: 280px;
  }

  .stat {
    padding-inline: clamp(.85rem, 2vw, 1.4rem) .35rem;
  }
}

/* Tablet landscape — hero stacks. The photograph leads, capped so it does not
   become the whole first screen, and the copy gets the full measure back. */
@media (max-width: 960px) {
  .hero__inner {
    grid-template-columns: 1fr;
  }

  .hero__content {
    max-width: none;
  }

  .hero__title {
    max-width: 20ch;
  }

  .hero__subtitle {
    max-width: 52ch;
  }

  .hero__visual {
    order: -1;
    min-height: 0;
  }

  .hero__photo {
    width: 100%;
    max-width: 540px;
    margin-inline: auto;
    margin-top: 0;
    margin-bottom: var(--space-4);
  }

  .hero__photo::before {
    inset: 2.25rem -.6rem -1.2rem 36%;
  }

  /* Two columns of stats; the second column loses its rule at the wrap */
  .stats__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-5) 0;
  }

  .stat:nth-child(odd) {
    padding-left: 0;
    border-left: 0;
  }

  .stat__label {
    max-width: 24ch;
  }
}

/* Tablet portrait — the page-hero masthead tightens but keeps its column rule */
@media (max-width: 860px) {
  .page-hero__icon {
    width: 68px;
    height: 68px;
    font-size: 1.6rem;
  }

  .page-hero h1 {
    max-width: none;
  }

  .hero__trust li,
  .page-hero__facts li {
    padding-inline: clamp(.6rem, 2vw, 1rem);
  }
}

/* Mobile — every ruled column set becomes a plain stack. Rules read as noise
   at one item per row, so they come off entirely rather than shrinking. */
@media (max-width: 620px) {
  .hero {
    padding-block: var(--space-5) var(--space-6);
  }

  .hero__title {
    line-height: 1.06;
    max-width: none;
  }

  .hero__photo {
    padding-inline: 1rem;
    margin-bottom: var(--space-5);
  }

  .hero__photo::before {
    inset: auto -.5rem -1rem 38%;
    height: 62%;
  }

  .hero__photo .hero__card--main {
    bottom: 1rem;
    max-width: min(78%, 260px);
  }

  .hero__card--main {
    padding: 1.05rem 1.15rem;
    gap: .8rem;
  }

  .hero__avatar {
    width: 44px;
    height: 44px;
    font-size: 1.15rem;
  }

  .hero__card-title {
    font-size: var(--fs-sm);
  }

  .hero__trust,
  .page-hero__facts {
    grid-template-columns: 1fr;
    gap: .7rem;
    padding-top: var(--space-3);
  }

  .hero__trust li,
  .page-hero__facts li {
    padding-inline: 0;
    border-left: 0;
  }

  /* Masthead stacks; the vertical rule has nothing left to divide */
  .page-hero {
    padding-block: var(--space-5);
  }

  .page-hero__inner {
    grid-template-columns: 1fr;
    gap: var(--space-3);
  }

  .page-hero__body {
    border-left: 0;
    padding-left: 0;
  }

  .page-hero__actions {
    margin-top: var(--space-4);
  }

  .page-hero__actions .btn {
    width: 100%;
  }
}

/* Very small phones */
@media (max-width: 400px) {
  .hero__card--float {
    display: none;
  }

  .hero__photo::before {
    inset: auto -.35rem -.75rem 42%;
    height: 55%;
  }

  .hero__photo .hero__card--main {
    left: 0;
    bottom: .75rem;
    max-width: 88%;
  }

  .stats__grid {
    grid-template-columns: 1fr;
    gap: var(--space-4);
  }

  .stat {
    padding-inline: 0;
    border-left: 0;
  }

  .stat__label {
    max-width: none;
  }
}


/* ---------- CARDS & BENTO ---------- */

/* ==========================================================================
   21. CARD SYSTEM — editorial refinement
   Appended override layer. Scope: .service-card (+ __icon __title __more
   __media), .service-card--cta, .feature, .highlight, .funding-card, .card,
   .tag-list and the .bento tile spans. Visual only — no markup, JS or
   behaviour changes.
   ========================================================================== */


/* Two elevation recipes the whole card family shares. The site's --shadow-*
   tokens are general-purpose; cards need a tighter contact shadow plus a wide,
   low-opacity ambient one so a grid of them reads as paper on a surface rather
   than as boxes with a grey halo. The hover shadow is tinted with the plum-900
   ink instead of the neutral navy — warm depth, matching the brand. */
:root {
  --shadow-card: 0 1px 2px rgba(6, 24, 47, .05), 0 10px 24px -14px rgba(6, 24, 47, .30);
  --shadow-card-hover: 0 2px 4px rgba(6, 24, 47, .06), 0 22px 44px -20px rgba(38, 9, 63, .34);
}


/* ---- Shared layering scaffold ---------------------------------------------
   `isolation` gives each card its own stacking context so the hover spotlight
   can sit at z-index -1 — above the card's own background, below its text.
   Without it a negative-z child would paint behind the card entirely. */
.service-card,
.highlight,
.feature,
.funding-card {
  position: relative;
  isolation: isolate;
}

/* The spotlight: a very faint teal wash anchored where the icon sits, so hover
   reads as light falling on the card rather than as a colour change. Ends at
   8% alpha, which leaves body copy at 9.1:1 — no contrast cost. */
.service-card::after,
.highlight::after,
.feature::after,
.funding-card::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(115% 100% at 14% 0%,
      rgba(0, 144, 156, .08), rgba(0, 144, 156, 0) 62%);
  transition: opacity 300ms cubic-bezier(.4, 0, .2, 1);
}

.service-card:hover::after,
.highlight:hover::after,
.feature:hover::after,
.funding-card:hover::after {
  opacity: 1;
}

/* One transition list for the family. It has to re-state opacity/transform
   because js/main.js adds `.reveal` to every one of these elements and that
   rule's own `transition` would otherwise be the last word — which is why
   hover shadows currently snap. Entrance fade keeps its 600ms; the hover
   response gets a shorter, matched curve. */
.service-card,
.highlight,
.feature,
.funding-card {
  transition: opacity 600ms ease,
    transform 300ms cubic-bezier(.4, 0, .2, 1),
    box-shadow 300ms cubic-bezier(.4, 0, .2, 1),
    border-color var(--transition),
    background-color var(--transition);
}

/* Rest and hover elevation. The hover border moves from --teal-400 to
   --teal-500: 2.55:1 against white was under the 3:1 floor for a meaningful
   edge, 3.84:1 clears it. */
.service-card,
.highlight,
.feature,
.funding-card {
  box-shadow: var(--shadow-card);
}

.service-card:hover,
.highlight:hover,
.feature:hover,
.funding-card:hover {
  border-color: var(--teal-500);
  box-shadow: var(--shadow-card-hover);
}

.service-card:hover {
  transform: translateY(-6px);
}

.highlight:hover,
.feature:hover,
.funding-card:hover {
  transform: translateY(-4px);
}

/* Press settles the card back down, so the whole tile answers a click the way
   a .btn does — hover lift, active settle, focus ring. */
.service-card:has(.service-card__more:active) {
  transform: translateY(-1px);
  box-shadow: var(--shadow-card);
}


/* ---- Service card: internal rhythm ---------------------------------------- */

/* Slightly more padding and a wider clamp — the old 1.5–2rem range let the
   copy run to the edge on the wide bento tiles. */
.service-card {
  padding: clamp(1.6rem, 2.6vw, 2.25rem);
  border-radius: var(--r-lg);
}

/* The top accent wipes with transform rather than width: scaleX composites on
   the GPU and can't force a layout pass on a six-tile grid. Plum→teal mirrors
   the logo lockup instead of a flat teal bar. */
.service-card::before {
  width: 100%;
  height: 3px;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--plum-700), var(--teal-500));
  transition: transform 320ms cubic-bezier(.4, 0, .2, 1);
}

.service-card:hover::before {
  transform: scaleX(1);
}

/* The icon gets a coloured shadow so it detaches from the card surface — depth
   by layering, which is the one place this family can afford it. */
.service-card__icon {
  width: 58px;
  height: 58px;
  border-radius: var(--r-md);
  font-size: 1.35rem;
  margin-bottom: var(--space-3);
  box-shadow: 0 8px 18px -9px rgba(0, 92, 102, .75);
}

/* Title / body / meta need three clearly different weights of voice. Tighter
   tracking and leading on the title, a measure cap on the body so wide tiles
   don't produce 90-character lines. */
.service-card__title {
  margin-bottom: var(--space-1);
  line-height: 1.24;
  letter-spacing: -.018em;
}

.service-card p {
  color: var(--ink-700);
  line-height: 1.62;
  max-width: 46ch;
}

/* Tags read as quiet metadata, not stickers: lighter fill at rest, a hairline
   to hold the pill shape, and the fill *darkens* on card hover so the response
   is a step up rather than a step down. plum-700 stays at 9.1:1 / 8.2:1. */
.tag-list {
  gap: .45rem;
}

.tag-list li {
  padding: .26rem .72rem;
  background: var(--teal-050);
  border: 1px solid var(--teal-100);
  color: var(--plum-700);
  letter-spacing: .005em;
  transition: background var(--transition), border-color var(--transition);
}

.service-card:hover .tag-list li {
  background: var(--teal-100);
  border-color: var(--teal-500);
}

/* The action becomes a card footer: a hairline separates it from the tags so
   the card has a visible top-to-bottom structure instead of one soft stack. */
.service-card__more {
  display: flex;
  width: 100%;
  align-items: center;
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
  letter-spacing: .005em;
}

/* Photography sits flush to the tile edge; the hairline stops the image from
   bleeding visually into the copy below it. */
.service-card__media {
  border-bottom: 1px solid var(--line);
}


/* ---- Bento: make the feature tile unmistakably the lead -------------------- */

.bento {
  gap: clamp(1rem, 2.2vw, 1.75rem);
}

/* Dominance comes from three things at once — more padding, a bigger type
   step, and a rest elevation one level above its neighbours. */
.bento__feature {
  padding: clamp(1.6rem, 3vw, 2.75rem);
  box-shadow: var(--shadow-md);
}

.bento__feature .service-card__title {
  font-size: calc(var(--fs-h3) * 1.2);
}

.bento__feature p {
  font-size: var(--fs-md);
  max-width: 52ch;
}

.bento__feature:hover {
  box-shadow: var(--shadow-card-hover);
}

/* Media bleeds to the tile edge; margin has to track the padding clamp above.
   Bottom margin is 0 so the icon can overlap the photo. */
.bento__feature .service-card__media {
  margin: calc(-1 * clamp(1.6rem, 3vw, 2.75rem)) calc(-1 * clamp(1.6rem, 3vw, 2.75rem)) 0;
  min-height: 290px;
}

/* The icon straddles the photo edge — the editorial signature that stops the
   feature tile reading as "the same card, but wider". `position` is required:
   the <img> is inline content and would otherwise paint over a static sibling.
   The ring colour has to match the card fill, which flips with the section. */
.bento__feature .service-card__icon {
  position: relative;
  width: 68px;
  height: 68px;
  font-size: 1.6rem;
  border-radius: var(--r-lg);
  margin-top: -2rem;
  box-shadow: 0 0 0 5px var(--off-white), 0 12px 26px -10px rgba(0, 92, 102, .7);
}

.section:not(.section--tint) .bento__feature .service-card__icon {
  box-shadow: 0 0 0 5px var(--white), 0 12px 26px -10px rgba(0, 92, 102, .7);
}

/* The two narrow tiles step down instead of shouting at the same volume as
   the half-width ones — a real three-level hierarchy across the grid. */
.bento__sm .service-card__icon {
  width: 46px;
  height: 46px;
  font-size: 1.1rem;
  border-radius: var(--r-sm);
}

.bento__sm .service-card__title {
  font-size: var(--fs-lg);
}


/* ---- CTA tile: a band, not a tall box -------------------------------------
   Full-width in the grid but stacked vertically, it wasted its span. Two
   columns with the button parked on the right turns it into a closing band.
   Row/column placement is explicit because the tile has exactly three
   children (title, paragraph, button). */
.service-card--cta {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  column-gap: clamp(1.5rem, 4vw, 3.5rem);
  padding-block: clamp(1.9rem, 4vw, 3rem);
}

.service-card--cta .service-card__title {
  grid-column: 1;
  grid-row: 1;
  font-size: calc(var(--fs-h3) * 1.15);
}

.service-card--cta p {
  grid-column: 1;
  grid-row: 2;
  margin: 0;
  max-width: 54ch;
  color: #e6f1f3;
  /* 5.06:1 on --teal-600, the gradient's lightest end */
}

.service-card--cta .btn {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  justify-self: end;
  margin-top: 0;
}

/* Static sheen anchored over the plum end of the gradient — deliberately not
   the teal end, where a white wash would drag the body copy under 4.5:1. */
.service-card--cta::after {
  opacity: 1;
  background: radial-gradient(85% 130% at 8% -10%,
      rgba(255, 255, 255, .12), rgba(255, 255, 255, 0) 62%);
}

/* Re-state: the gradient accent bar above would be invisible on this tile. */
.service-card--cta::before {
  background: var(--teal-400);
}

.service-card--cta:hover {
  border-color: transparent;
}


/* ---- Highlight / feature / funding: one icon language ---------------------
   All three used flat teal tints of different values. A shared chip — soft
   vertical gradient, hairline ring, small contact shadow — makes them read as
   one system. Glyph is --teal-600: 5.4:1 on --teal-050, 4.8:1 on --teal-100. */
.highlight__icon,
.feature__icon,
.funding-card__icon {
  background: linear-gradient(160deg, var(--teal-050), var(--teal-100));
  box-shadow: inset 0 0 0 1px rgba(0, 144, 156, .22), 0 3px 8px -4px rgba(0, 92, 102, .5);
  color: var(--teal-600);
}

.highlight {
  padding: clamp(1.6rem, 2.4vw, 1.9rem) clamp(1.4rem, 2.2vw, 1.7rem);
  border-radius: var(--r-lg);
}

.highlight__icon {
  width: 52px;
  height: 52px;
  border-radius: var(--r-md);
  margin-bottom: var(--space-3);
}

.highlight h3 {
  margin-bottom: var(--space-1);
  line-height: 1.28;
  letter-spacing: -.014em;
}

.highlight p {
  line-height: 1.6;
}

.feature {
  gap: 1.1rem;
  align-items: flex-start;
  padding: clamp(1.4rem, 2.2vw, 1.6rem);
}

.feature__icon {
  width: 46px;
  height: 46px;
  border-radius: var(--r-md);
}

.feature h3 {
  line-height: 1.3;
  letter-spacing: -.014em;
}

.feature p {
  line-height: 1.6;
}

.funding-card {
  padding: clamp(1.6rem, 2.6vw, 2.1rem);
}

.funding-card__icon {
  width: 64px;
  height: 64px;
  margin-bottom: var(--space-3);
}

.funding-card h3 {
  margin-bottom: var(--space-1);
  letter-spacing: -.014em;
}

.funding-card p {
  line-height: 1.6;
}


/* ---- Generic panel card --------------------------------------------------- */

/* A larger radius and looser padding separate the long-form panel from the
   compact tiles around it — different job, different proportions. */
.card {
  border-radius: var(--r-xl);
  padding: clamp(1.6rem, 3vw, 2.5rem);
  box-shadow: var(--shadow-card);
}

/* The bare glyph beside the title floated; a chip anchors it to the icon
   language used everywhere else on the page. */
.card__title {
  gap: .8rem;
  align-items: center;
  letter-spacing: -.016em;
}

.card__title i {
  display: grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  flex-shrink: 0;
  border-radius: var(--r-md);
  background: linear-gradient(160deg, var(--teal-050), var(--teal-100));
  box-shadow: inset 0 0 0 1px rgba(0, 144, 156, .22);
  color: var(--teal-600);
  font-size: .95rem;
}


/* ==========================================================================
   CARD SYSTEM — RESPONSIVE
   ========================================================================== */

/* Once the narrow tiles widen to halves they're the same size as their
   neighbours, so the deliberate step-down no longer makes sense. */
@media (max-width: 960px) {
  .bento__sm .service-card__icon {
    width: 58px;
    height: 58px;
    font-size: 1.35rem;
    border-radius: var(--r-md);
  }

  .bento__sm .service-card__title {
    font-size: var(--fs-h3);
  }
}

/* Below the drawer breakpoint the CTA band has no room for a side-by-side
   button — back to a single column, button on its own row. */
@media (max-width: 860px) {
  .service-card--cta {
    grid-template-columns: 1fr;
  }

  .service-card--cta .service-card__title {
    grid-row: 1;
  }

  .service-card--cta p {
    grid-row: 2;
  }

  .service-card--cta .btn {
    grid-column: 1;
    grid-row: 3;
    justify-self: start;
    margin-top: var(--space-3);
  }
}

@media (max-width: 620px) {

  /* Full-width button on phones, as the rest of the site already does */
  .service-card--cta .btn {
    justify-self: stretch;
  }

  /* The overlapping icon needs less overlap at a narrower measure */
  .bento__feature .service-card__icon {
    margin-top: -1.5rem;
  }

  .bento__feature .service-card__media {
    min-height: 220px;
  }

  .bento__feature .service-card__title {
    font-size: var(--fs-h3);
  }

  .bento__feature p {
    font-size: var(--fs-sm);
  }

  .feature__icon {
    width: 44px;
    height: 44px;
  }
}

@media (max-width: 400px) {
  .service-card__icon {
    width: 50px;
    height: 50px;
    font-size: 1.2rem;
  }

  .funding-card__icon {
    width: 56px;
    height: 56px;
  }

  .tag-list li {
    padding: .24rem .6rem;
  }
}


/* ==========================================================================
   CARD SYSTEM — REDUCED MOTION
   Re-stated here because these selectors are appended after the stylesheet's
   own reduce block and would otherwise win the cascade. Colour, shadow and
   border feedback all stay — only movement goes.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {

  .service-card:hover,
  .highlight:hover,
  .feature:hover,
  .funding-card:hover,
  .service-card:has(.service-card__more:active) {
    transform: none;
  }

  .service-card:hover .service-card__icon,
  .highlight:hover .highlight__icon,
  .feature:hover .feature__icon,
  .funding-card:hover .funding-card__icon,
  .service-card:hover .service-card__more i,
  .service-card:hover .service-card__media img {
    transform: none;
  }

  /* The accent bar appears instead of wiping, so the hover affordance survives */
  .service-card::before {
    transition: none;
    transform: scaleX(1);
    opacity: 0;
  }

  .service-card:hover::before {
    opacity: 1;
  }

  .service-card::after,
  .highlight::after,
  .feature::after,
  .funding-card::after {
    transition: none;
  }

  .service-card,
  .highlight,
  .feature,
  .funding-card {
    transition: none;
  }

  .reveal {
    opacity: 1;
    transform: none;
  }
}


/* ---------- CONTENT SECTIONS ---------- */

/* ==========================================================================
   21. EDITORIAL CONTENT BLOCKS  (appended — overrides §3, §10, §11, §15, §16)

   Scope: in-page content blocks only — sections, heads, accordion, steps,
   callout, quote, check-list, trust row, CTA band, photography, legal prose.
   Nothing here touches the header, hero, cards, forms or footer.

   The problem being fixed: every section resolved to "centred heading over a
   grid", so the page had one rhythm from top to bottom. The fixes below are
   all structural rather than decorative — a seam between sections, a rule that
   starts a sub-block, a hairline list instead of a stack of boxes — so each
   band reads as a different kind of thing.

   Constraints honoured:
     • The accordion's 0fr→1fr grid mechanism is preserved exactly. Bottom
       padding still lives on .accordion__panel and still animates. Nothing
       gains padding or a border on .accordion__panel > *.
     • No transform / opacity / transition shorthand is declared on any
       scroll-reveal target (.section__head, .callout, .step, .accordion__item,
       .trust-row, .split__body, .split__media) — that would out-cascade
       .reveal, which is defined earlier in the file.
     • Overlays on the two gradient surfaces darken only (plum-900), never
       lighten, so the lightest colour either surface reaches is still exactly
       --teal-600 and every stated ratio holds.
   ========================================================================== */


/* ---- 21.1 Section rhythm & seams -----------------------------------------
   More air between bands, and a visible seam where the ground changes colour.
   The tint band also gets the same corner wash the hero uses, so a white
   section reads as a lit panel rather than a flat slab. */
.section {
  padding-block: clamp(4rem, 8vw, 7.5rem);
}

/* The first band after a page hero belongs to the hero — pull it up so the
   two read as one opening move instead of two stacked slabs. */
.page-hero+.section {
  padding-top: clamp(2.75rem, 5.5vw, 4.5rem);
}

.section--tint {
  border-block: 1px solid var(--line);
  background:
    radial-gradient(46rem 24rem at 92% -12%, var(--teal-050) 0%, rgba(235, 248, 250, 0) 62%),
    var(--white);
}


/* ---- 21.2 Section heads, eyebrow, rule -----------------------------------
   Tighter measure on the lede, and the centred head finally centres its rule
   (it was inheriting the left-aligned margin and hanging off-axis). */
.section__head {
  margin-bottom: clamp(2.5rem, 4.5vw, 4rem);
}

.section__head:not(.section__head--left):not(.section__head--split) .section__lede {
  max-width: 58ch;
  margin-inline: auto;
}

.section__head:not(.section__head--left):not(.section__head--split) .rule {
  margin-inline: auto;
}

.section__lede {
  line-height: 1.65;
}

/* Head left, lede right, divided by a hairline — the split head's whole point
   is that the two halves are different things, so show the join. */
.section__head--split .section__lede {
  padding-left: clamp(1.25rem, 2.5vw, 2rem);
  border-left: 1px solid var(--line);
}

/* Editorial tick before an icon-less eyebrow. currentColor so it inherits the
   label's own contrast on light and dark grounds alike; :has() keeps it off
   the eyebrows that already carry a Font Awesome glyph. */
.eyebrow {
  margin-bottom: var(--space-3);
}

.eyebrow:not(:has(i))::before {
  content: '';
  width: 1.5rem;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  opacity: .55;
  flex-shrink: 0;
}

.rule {
  width: 72px;
}


/* ---- 21.3 Split ----------------------------------------------------------
   Top-aligned rather than centred: aligning the heading with the top of the
   photograph is what makes an asymmetric two-column read as designed. */
.split {
  grid-template-columns: 1.08fr .92fr;
  gap: clamp(1.75rem, 5vw, 4rem);
  align-items: start;
}

.split__body>h2 {
  margin-bottom: var(--space-3);
}

.split__body p {
  max-width: 62ch;
}

/* The sub-head starts a new movement inside the column, so it gets a rule */
.split__subhead {
  margin-top: var(--space-5);
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
}


/* ---- 21.4 Check list -----------------------------------------------------
   Hairline-separated rows instead of a tight bulleted clump: easier to scan
   line by line, and it gives the column a visible baseline grid. */
.check-list {
  gap: 0;
  margin-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.check-list li {
  gap: .85rem;
  padding-block: .8rem;
  border-bottom: 1px solid var(--line);
}

.check-list i {
  display: grid;
  place-items: center;
  width: 1.6rem;
  height: 1.6rem;
  margin-top: .18rem;
  border-radius: 50%;
  background: var(--teal-050);
  color: var(--teal-600);
  /* 5.37:1 on --teal-050 */
  font-size: .8rem;
}

/* On a white band the disc needs its own edge or it disappears */
.section--tint .check-list i {
  box-shadow: inset 0 0 0 1px var(--teal-100);
}


/* ---- 21.5 Callout --------------------------------------------------------
   Was a 2px box with an 8px left slab — loud, and the slab colour (--teal-400,
   2.35:1 on --teal-050) was too weak to be carrying that much weight. Now a
   hairline panel with a gradient spine and a lifted icon chip. */
.callout {
  position: relative;
  overflow: hidden;
  gap: clamp(1rem, 2.5vw, 1.75rem);
  align-items: center;
  max-width: 62rem;
  margin-bottom: clamp(2.5rem, 5vw, 3.75rem);
  padding: clamp(1.6rem, 3vw, 2.4rem);
  padding-left: calc(clamp(1.6rem, 3vw, 2.4rem) + 6px);
  border: 1px solid var(--teal-500);
  /* 3.54:1 on --teal-050 — AA for a UI edge */
  border-left-width: 1px;
  border-radius: var(--r-lg);
  background: var(--teal-050);
  box-shadow: var(--shadow-sm);
}

/* Brand spine. Absolute rather than a border so the panel keeps its radius. */
.callout::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 6px;
  background: linear-gradient(180deg, var(--plum-700), var(--teal-500));
}

.callout__icon {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  margin-top: 0;
  border-radius: 50%;
  background: var(--white);
  border: 1px solid var(--teal-100);
  color: var(--teal-600);
  /* 5.83:1 on --white */
  font-size: 1.3rem;
  box-shadow: var(--shadow-sm);
}

.callout__body {
  min-width: 0;
}

/* Display face: a callout is a statement, not a label, so it reads as a
   headline rather than a card title. */
.callout__title {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.015em;
  margin-bottom: var(--space-2);
}

.callout p {
  max-width: 64ch;
}

/* --ink-700, 9.23:1 on --teal-050 */


/* ---- 21.6 Steps ----------------------------------------------------------
   The process block now opens with a rule and a left-aligned title, so it
   announces itself as a sub-section instead of being a second centred heading
   under the first one. Markers become outlined serif numerals — lighter on the
   page, and the connector threads between them instead of under them. */
.steps {
  border-top: 1px solid var(--line);
  padding-top: clamp(2.25rem, 4.5vw, 3.25rem);
}

.steps__title {
  text-align: left;
  margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem);
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em;
}

.steps__list {
  /* Layout-only local property (no colour): the connector has to know the
     column gap to reach the next marker, and reading it twice would drift. */
  --step-gap: clamp(1.25rem, 2.5vw, 2.25rem);
  gap: clamp(2rem, 4vw, 2.75rem) var(--step-gap);
}

.step {
  padding-top: 0;
}

.step__num {
  position: relative;
  z-index: 1;
  /* opaque fill occludes the connector */
  width: 54px;
  height: 54px;
  margin-bottom: var(--space-3);
  background: var(--white);
  border: 2px solid var(--teal-500);
  /* 3.84:1 on --white — AA for a UI edge */
  color: var(--plum-800);
  /* 12.52:1 on --white */
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.4rem;
  letter-spacing: 0;
}

/* Continuous hairline from this marker to the next, fading as it travels */
.step::after {
  top: 26px;
  left: calc(54px + .5rem);
  width: calc(100% + var(--step-gap) - 54px - 1rem);
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--line-strong), var(--line));
}

.step h4 {
  margin-bottom: .3rem;
}

/* Ring colour lifted from --teal-050 to --teal-100 so it still reads against
   the now-white marker fill. Motion for this hover is killed in §18. */
.step:hover .step__num {
  box-shadow: 0 0 0 6px var(--teal-100);
}


/* ---- 21.7 Accordion ------------------------------------------------------
   Resting state is now a hairline-ruled list of questions, not a stack of
   boxes: quiet at rest, and the open row becomes a tinted band with a brand
   spine, so open vs closed is obvious without relying on the chevron alone.

   ⚠ THE PANEL MECHANISM IS UNCHANGED. .accordion__panel stays a one-row grid
   animating 0fr→1fr, its child keeps overflow:hidden / min-height:0 and gains
   NO padding and NO border (either would give the collapsed track a minimum
   height and leave a visible strip). The bottom padding stays on the panel and
   still transitions alongside grid-template-rows. Extra breathing room above
   the answer is taken from the TRIGGER's bottom padding instead — that element
   is outside the grid-track mechanism entirely. */
.accordion {
  gap: 0;
  border-top: 1px solid var(--line);
}

.accordion__item {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  overflow: hidden;
}

/* No transition declared here on purpose: .accordion__item is a scroll-reveal
   target, and main.js writes an inline transition-delay of up to 210ms onto
   it. A transition would inherit that delay and make the click feel broken. */
.accordion__item:has(.accordion__trigger[aria-expanded="true"]) {
  background: var(--teal-050);
  border-bottom-color: var(--teal-500);
  /* 3.54:1 on --teal-050 */
  box-shadow: inset 3px 0 0 var(--teal-500);
}

.accordion__trigger {
  gap: 1.25rem;
  padding: 1.35rem 1.4rem;
  line-height: 1.35;
  transition: color var(--transition), background var(--transition),
    padding-bottom var(--transition);
}

.accordion__trigger:hover {
  background: var(--teal-050);
  color: var(--teal-600);
  /* 5.37:1 on --teal-050 */
}

/* Closes the gap between a question and its own answer */
.accordion__trigger[aria-expanded="true"] {
  padding-bottom: .85rem;
}

/* Chevron becomes a chip that fills on open — a second, non-rotational signal
   for anyone who can't perceive the 180° flip. */
.accordion__chevron {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--white);
  border: 1px solid var(--teal-100);
  color: var(--teal-600);
  /* 5.83:1 on --white */
  font-size: .8rem;
  transition: transform var(--transition), background var(--transition),
    border-color var(--transition), color var(--transition);
}

.accordion__trigger[aria-expanded="true"] .accordion__chevron {
  background: var(--teal-600);
  border-color: var(--teal-600);
  color: var(--white);
  /* 5.83:1 on --teal-600 */
}

/* Side padding constant, bottom padding animates with the row — as before. */
.accordion__panel {
  padding: 0 1.4rem;
  padding-bottom: 0;
  line-height: 1.7;
}

.accordion__panel.is-open {
  padding-bottom: 1.5rem;
}

/* Measure only. No padding, no border, no margin — see the warning above. */
.accordion__panel>* {
  max-width: 64ch;
}


/* ---- 21.8 Quote ----------------------------------------------------------
   A pull-quote rather than a tinted box: display face, larger, with the mark
   hung at the top and the attribution behind a rule.
   The bloom is plum-900 and therefore DARKENS the surface — the lightest
   colour this panel reaches is still exactly --teal-600, which is what every
   ratio below is measured against. */
.quote {
  isolation: isolate;
  overflow: hidden;
  padding: clamp(1.85rem, 3.5vw, 2.75rem);
  border: 1px solid rgba(255, 255, 255, .20);
  /* decorative glass edge */
  border-radius: var(--r-xl);
  background: linear-gradient(140deg, var(--plum-800) 0%, var(--plum-700) 42%, var(--teal-600) 100%);
  box-shadow: var(--shadow-lg);
}

.quote::before {
  content: '';
  position: absolute;
  z-index: -1;
  /* under the copy, over the gradient */
  inset: auto -30% -45% -25%;
  height: 26rem;
  background: radial-gradient(circle, rgba(38, 9, 63, .38) 0%, rgba(38, 9, 63, 0) 68%);
  pointer-events: none;
}

/* Kept in flow: nothing sits on top of it, so it can't erode the copy's
   contrast the way a watermarked mark behind the text would. */
.quote i.quote__mark {
  font-size: clamp(2.4rem, 4.5vw * var(--a11y-zoom, 1), 3.4rem);
  line-height: .8;
  color: rgba(255, 255, 255, .32);
  margin: 0 0 var(--space-3) -.06em;
}

.quote p {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.15rem, .7vw * var(--a11y-zoom, 1) + 1rem, 1.4rem);
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--white);
  /* 5.83:1 on --teal-600 */
  max-width: 46ch;
  margin-bottom: var(--space-4);
}

.quote cite {
  display: inline-block;
  padding-top: var(--space-3);
  border-top: 1px solid rgba(255, 255, 255, .28);
  color: #E9F4F6;
  /* 5.20:1 on --teal-600 */
  letter-spacing: .01em;
}

.quote--under {
  margin-top: clamp(3.25rem, 5vw, 4.25rem);
}


/* ---- 21.9 Photography ----------------------------------------------------
   The photo now lifts off its offset block instead of sitting flush on it, and
   the block's edge moves from --teal-400 (2.55:1) to --teal-500 (3.61:1 on
   --off-white) so the frame reads as a deliberate shape at AA. */
.photo {
  box-shadow: var(--shadow-md);
}

.photo-frame .photo {
  box-shadow: var(--shadow-lg);
}

.photo-frame::before {
  inset: 2rem -2rem -2rem 2rem;
  background: linear-gradient(140deg, var(--teal-100), var(--teal-050));
  border: 1px solid var(--teal-500);
}

.photo-frame--right::before {
  inset: 2rem 2rem -2rem -2rem;
}

.photo__tag {
  left: 1.15rem;
  bottom: 1.15rem;
  padding: .65rem 1.05rem;
  /* 90% white: over a black frame that still composites to #E6E6E6, where
     --plum-800 measures 10.03:1 — the worst case is comfortably AA. */
  background: rgba(255, 255, 255, .90);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, .70);
  box-shadow: var(--shadow-lg);
  letter-spacing: .01em;
}


/* ---- 21.10 Trust row -----------------------------------------------------
   Reads as the section's footnote now, sitting under its own rule. */
.trust-row {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
  gap: .75rem clamp(1.5rem, 4vw, 3rem);
}


/* ---- 21.11 CTA band ------------------------------------------------------
   Same plum→teal idiom, but with depth and an accent rule so the closing band
   doesn't read as the flat slab it was. The bloom is plum-900 — it darkens
   only, so the lightest colour reached is still exactly --teal-600. */
.cta-band {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  color: #E9F4F6;
  /* 5.20:1 on --teal-600 */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18);
  padding-block: clamp(3.25rem, 7vw, 5.25rem);
}

.cta-band::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: -35% -15% auto auto;
  width: 40rem;
  height: 40rem;
  background: radial-gradient(circle, rgba(38, 9, 63, .42) 0%, rgba(38, 9, 63, 0) 66%);
  pointer-events: none;
}

.cta-band__inner {
  gap: clamp(var(--space-4), 5vw, var(--space-6));
  align-items: end;
}

.cta-band h2 {
  margin-bottom: var(--space-3);
}

/* Accent rule above the heading — decorative, mirrors .rule on light bands */
.cta-band h2::before {
  content: '';
  display: block;
  width: 64px;
  height: 4px;
  margin-bottom: var(--space-3);
  border-radius: 4px;
  background: linear-gradient(90deg, var(--white), var(--teal-400));
}

.cta-band p {
  max-width: 52ch;
}

/* #E9F4F6, 5.20:1 on --teal-600 */
.cta-band__actions {
  align-self: end;
}


/* ---- 21.12 Legal prose ---------------------------------------------------
   Measure was 820px (~78 characters at 17px) which is well past comfortable
   for a policy read; 68ch with 1.78 leading is the target. Each numbered
   clause now opens under a rule, so the document has visible structure when
   scanned rather than only when read. */
.prose {
  max-width: 68ch;
}

.prose p,
.prose li {
  line-height: 1.78;
}

.prose p {
  margin-bottom: var(--space-4);
}

.prose h2 {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
  font-size: clamp(1.35rem, 1vw * var(--a11y-zoom, 1) + 1.1rem, 1.7rem);
  line-height: 1.25;
}

.prose h2:first-of-type {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.prose h3 {
  margin-top: var(--space-5);
  margin-bottom: var(--space-2);
}

.prose ul,
.prose ol {
  padding-left: 1.6rem;
  margin-bottom: var(--space-4);
  gap: .65rem;
}

.prose li {
  padding-left: .2rem;
}

.prose li::marker {
  font-weight: 800;
}

/* Terms of art carry the brand colour so definitions are findable in a wall
   of policy text. --plum-800 measures 12.52:1 on white. */
.prose strong {
  color: var(--plum-800);
}

.prose em {
  color: var(--ink-900);
}

/* Legal copy must never rely on colour alone to signal a link */
.prose a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  font-weight: 700;
  /* --teal-600, 5.83:1 on white */
}

.prose .updated {
  background: var(--teal-050);
  border: 1px solid var(--teal-500);
  color: var(--plum-700);
  /* 9.08:1 on --teal-050 */
  padding: .4rem 1rem;
  margin-bottom: var(--space-5);
}


/* ---- 21.13 Reduced motion ------------------------------------------------
   §18 already collapses every duration to .01ms; these make the intent
   explicit for the transitions introduced above and make sure the accordion
   simply snaps to its end state rather than easing to it. */
@media (prefers-reduced-motion: reduce) {

  .accordion__panel,
  .accordion__trigger,
  .accordion__chevron {
    transition: none;
  }

  /* Colour and the filled chevron chip still carry the state change */
  .step:hover .step__num {
    transform: none;
    box-shadow: 0 0 0 6px var(--teal-100);
  }
}


/* ---- 21.14 Responsive ----------------------------------------------------
   Breakpoints match the five the site already defines. */

@media (max-width: 1080px) {

  /* Pull the offset block in before it starts crowding the page gutter */
  .photo-frame::before {
    inset: 1.5rem -1.5rem -1.5rem 1.5rem;
  }

  .photo-frame--right::before {
    inset: 1.5rem 1.5rem -1.5rem -1.5rem;
  }
}

@media (max-width: 960px) {

  /* The split head is one column here, so the dividing hairline has no job */
  .section__head--split .section__lede {
    padding-left: 0;
    border-left: 0;
  }

  .split {
    grid-template-columns: 1fr;
  }

  .cta-band__inner {
    align-items: flex-start;
  }

  .cta-band__actions {
    align-self: flex-start;
  }

  .quote p {
    max-width: none;
  }
}

@media (max-width: 860px) {
  .callout {
    align-items: flex-start;
  }

  .callout__icon {
    width: 46px;
    height: 46px;
    font-size: 1.15rem;
  }
}

@media (max-width: 620px) {
  .section {
    padding-block: clamp(3.25rem, 9vw, 4.5rem);
  }

  .page-hero+.section {
    padding-top: clamp(2.5rem, 7vw, 3.5rem);
  }

  /* Spine moves to the top edge once the icon stacks above the copy */
  .callout {
    flex-direction: column;
    gap: var(--space-3);
    padding-left: clamp(1.6rem, 3vw, 2.4rem);
    padding-top: calc(clamp(1.6rem, 3vw, 2.4rem) + 6px);
  }

  .callout::before {
    width: 100%;
    height: 6px;
    bottom: auto;
  }

  .steps__list {
    gap: var(--space-4);
  }

  .step__num {
    width: 48px;
    height: 48px;
    font-size: 1.25rem;
  }

  .accordion__trigger {
    padding: 1.1rem 1.05rem;
    gap: .85rem;
  }

  .accordion__panel {
    padding-inline: 1.05rem;
  }

  .accordion__panel.is-open {
    padding-bottom: 1.25rem;
  }

  .accordion__chevron {
    width: 30px;
    height: 30px;
    font-size: .72rem;
  }

  .quote {
    padding: clamp(1.35rem, 5vw, 1.85rem);
  }

  .prose p {
    margin-bottom: var(--space-3);
  }

  .prose h2 {
    margin-top: var(--space-5);
  }

  .trust-row {
    justify-content: flex-start;
  }
}

@media (max-width: 400px) {
  .check-list i {
    width: 1.4rem;
    height: 1.4rem;
    font-size: .72rem;
  }

  .cta-band h2::before {
    width: 48px;
  }

  .photo-frame::before {
    inset: .85rem -.85rem -.85rem .85rem;
  }

  .photo-frame--right::before {
    inset: .85rem .85rem -.85rem -.85rem;
  }
}


/* ---------- FORMS ---------- */

/* ==========================================================================
   21. CONTACT & FORM — EDITORIAL REFRESH
   Appended after §20; every rule below re-states an existing §12 selector at
   equal or higher specificity so it overrides cleanly without !important.
   Visual only — no field, label, id, name, ARIA attribute or JS hook changes.
   The classes main.js §11/§11b toggle (.is-invalid, .is-valid, .is-loading)
   are all still styled here, and two of them (.is-loading, .is-invalid) now
   carry MORE meaning than before, not less.
   ========================================================================== */


/* ---- New token -----------------------------------------------------------
   The resting input border was --line-strong (#CCC0D9), which measures just
   1.73:1 against white. WCAG needs 3:1 for the boundary of a control, so on a
   phone in daylight the fields effectively had no edge at all — the single
   worst problem on this surface. --line-input is the same lavender grey pushed
   until it clears 3:1 on every ground a control actually sits on here:
     #8F819D on --white     (#FFFFFF) = 3.62:1
     #8F819D on --off-white (#F9F7FB) = 3.40:1
     #8F819D on --teal-050  (#EBF8FA) = 3.34:1
     #8F819D on --danger-bg (#FDECEA) = 3.17:1
   --line-strong is left untouched so nothing outside this section shifts. */
:root {
  --line-input: #8F819D;
}


/* ---- Contact grid --------------------------------------------------------
   More air between the dark panel and the form so they read as two considered
   objects rather than two columns jammed together. */
.contact__grid {
  grid-template-columns: .82fr 1.18fr;
  gap: clamp(1.5rem, 3vw, 3rem);
}

/* The sidebar holds the phone number — the escape hatch for anyone who gives
   up on the form. Pinning it keeps that number on screen for the whole scroll.
   Gated on viewport height as well as width so it can never trap a short
   window, and scoped above the 960px stack point where the aside goes full
   width. `top` matches the html scroll-padding-top so it clears the header. */
@media (min-width: 961px) and (min-height: 700px) {
  .contact__aside {
    position: sticky;
    top: 7.6rem;
  }
}


/* ---- Contact sidebar -----------------------------------------------------
   Flat --plum-800 made the panel read as a block of colour. A slow plum-800 →
   plum-900 gradient with one teal bloom in the bottom-right corner ties it to
   the logo lockup and to every other gradient surface on the site, and the
   --r-xl radius + --shadow-md now match the form panel opposite so the pair
   reads as one unit. Contrast of the existing #E1D6F0 body text is measured on
   the worst (lightest) point of the composite, the teal bloom itself:
     #E1D6F0 on the bloom (#3E3484 at .16 alpha) = 7.4:1
     #E1D6F0 on --plum-800 = 8.99:1, on --plum-900 = 12.64:1
     #FFFFFF (item headings) on the bloom = 10.35:1 */
.contact__aside {
  background:
    radial-gradient(88% 60% at 108% 106%, rgba(18, 180, 184, .16), transparent 62%),
    linear-gradient(168deg, var(--plum-800) 0%, var(--plum-900) 100%);
  border-radius: var(--r-xl);
  padding: clamp(1.6rem, 3vw, 2.35rem);
  box-shadow: var(--shadow-md);
}

/* A hairline under the title turns the panel into a titled card */
.contact__aside-title {
  margin-bottom: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid rgba(255, 255, 255, .18);
}

/* Each row becomes a real tappable surface: full-bleed hover/focus ground via
   the negative inline margin, 60px tall, divider only *between* rows. */
.contact__aside .contact-item {
  gap: 1rem;
  margin-inline: -.75rem;
  padding: .85rem .75rem;
  min-height: 60px;
  border-bottom: 0;
  border-radius: var(--r-md);
  transition: background var(--transition), color var(--transition);
}

.contact__aside .contact-item+.contact-item {
  border-top: 1px solid rgba(255, 255, 255, .14);
  border-radius: 0 0 var(--r-md) var(--r-md);
}

/* rgba(255,255,255,.10) over --plum-800 = #5A2F86; #E1D6F0 on it = 6.9:1,
   #FFFFFF on it = 9.6:1 — both still clear AA. */
.contact__aside a.contact-item:hover {
  background: rgba(255, 255, 255, .10);
}

.contact__aside a.contact-item:focus-visible {
  outline: 3px solid var(--teal-400);
  /* 4.9:1 on --plum-800, 6.9:1 on --plum-900 */
  outline-offset: 2px;
  border-radius: var(--r-md);
}

/* Glass chip, matching the .mobile-bar treatment named in DESIGN.md */
.contact-item__icon {
  width: 46px;
  height: 46px;
  border-radius: 14px;
  background: rgba(18, 180, 184, .18);
  border: 1px solid rgba(255, 255, 255, .14);
  backdrop-filter: blur(6px);
}

.contact-item strong {
  margin-bottom: .1rem;
  letter-spacing: .01em;
}

/* The confidentiality note is the trust cue — give it a glass card of its own.
   Worst case: rgba(255,255,255,.10) over the teal bloom = #514890;
   #E1D6F0 on it = 5.6:1 (AA body), --teal-400 icon on it = 3.1:1 (AA non-text). */
.contact__note {
  margin-top: var(--space-4);
  padding: 1rem 1.15rem;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, .10);
  backdrop-filter: blur(6px);
  line-height: 1.6;
}


/* ---- Form panel ----------------------------------------------------------
   Matches the sidebar's radius and elevation, and takes a 5px plum → teal cap
   so the two panels are visibly siblings. The cap is decorative only. */
.contact__form-wrap {
  position: relative;
  border-radius: var(--r-xl);
  padding: clamp(1.6rem, 3.2vw, 2.75rem);
  box-shadow: var(--shadow-md);
}

.contact__form-wrap::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 5px;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  background: linear-gradient(90deg, var(--plum-700), var(--teal-600));
}


/* ---- Intro, labels, rhythm ----------------------------------------------
   The intro line explains the asterisk, so it is instruction, not fine print:
   --ink-700 = 10.02:1 on white (was --ink-500 at 5.92:1). The rule under it
   separates it from the first field. */
.form__intro {
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--line);
  color: var(--ink-700);
}

.field label,
.fieldset legend {
  margin-bottom: .45rem;
  color: var(--plum-800);
  /* 12.52:1 on white */
  letter-spacing: .005em;
  line-height: 1.4;
}

/* The legend heads a group of six controls — size it as a sub-heading */
.form .fieldset legend {
  font-size: var(--fs-md);
}

.req {
  margin-left: .1em;
}

/* --danger on white = 6.54:1 */

/* Wider gaps between fields; a row is one rhythm unit, so its children stop
   double-spacing and the row itself carries the margin. */
.field {
  margin-bottom: var(--space-4);
}

.field-row {
  gap: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}

.field-row>.field {
  margin-bottom: 0;
}

/* Grouping without touching the HTML: a hairline and extra air before the
   service picker splits "who you are" from "what you need". */
.form .fieldset {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}


/* ---- Inputs --------------------------------------------------------------
   52px minimum (56px on phones, below), 17px text — above iOS's 16px zoom
   threshold and easier on older eyes than the previous 16px. Border moves to
   --line-input for the 3:1 edge. */
input[type="text"],
input[type="email"],
input[type="tel"],
select,
textarea {
  min-height: 3.25rem;
  padding: .9rem 1.05rem;
  font-size: var(--fs-base);
  line-height: 1.5;
  border-color: var(--line-input);
  transition: border-color var(--transition), box-shadow var(--transition),
    background var(--transition);
}

/* Restated: the min-height above would otherwise out-order §12's 120px */
textarea {
  min-height: 9rem;
  padding-top: .85rem;
}

input:hover,
select:hover,
textarea:hover {
  border-color: var(--ink-500);
}

/* 5.92:1 on white */

/* Focus: --teal-600 at 5.83:1 on white replaces --teal-500 at 3.84:1, and the
   halo is decorative — the 2px border alone already carries the state.
   §12 sets `outline: none` on :focus, which was also killing the global
   :focus-visible ring for keyboard users; this puts a solid 3px ring back and
   re-states border-radius, which the global rule flattens to 4px. */
input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--teal-600);
  box-shadow: 0 0 0 4px rgba(0, 112, 123, .16);
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 3px solid var(--teal-600);
  outline-offset: 3px;
  border-radius: var(--r-md);
}

::placeholder {
  color: var(--ink-500);
  /* 5.92:1 on white */
  opacity: 1;
}

/* Chevron re-seated for the new padding (image itself unchanged) */
select {
  background-position: right 1.05rem center;
  padding-right: 2.9rem;
}

/* An unchosen select should read as a prompt, not as an answer.
   --ink-500 = 5.92:1 on white, so it stays AA even as placeholder text. */
select:has(option[value=""]:checked) {
  color: var(--ink-500);
}

/* complaints.html disables the identity fields when "anonymous" is ticked.
   Disabled controls are exempt from contrast, but they should still look
   deliberately off rather than broken. */
input:disabled,
select:disabled,
textarea:disabled {
  background: var(--off-white);
  border-color: var(--line);
  cursor: not-allowed;
}


/* ---- Validation states ---------------------------------------------------
   Error: --danger border = 6.54:1 on white, far past the 3:1 edge floor;
   --ink-900 typed into the --danger-bg field = 15.78:1. */
.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea {
  border-color: var(--danger);
  background: var(--danger-bg);
}

.field.is-invalid input:focus,
.field.is-invalid select:focus,
.field.is-invalid textarea:focus {
  box-shadow: 0 0 0 4px rgba(179, 38, 30, .18);
}

.field.is-invalid input:focus-visible,
.field.is-invalid select:focus-visible,
.field.is-invalid textarea:focus-visible {
  outline-color: var(--danger);
  /* 6.54:1 on white */
}

/* Valid: quiet confirmation, not a second alarm. Teal edge everywhere plus a
   tick inside text inputs only — selects already carry the chevron there. */
.field.is-valid input,
.field.is-valid select,
.field.is-valid textarea {
  border-color: var(--teal-600);
}

/* 5.83:1 on white */
.field.is-valid input[type="text"],
.field.is-valid input[type="email"],
.field.is-valid input[type="tel"] {
  padding-right: 2.9rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2300707B' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1.05rem center;
  background-size: 17px;
}


/* ---- Hints & errors ------------------------------------------------------
   Both were 15px. A hint nobody can read is worse than no hint: 16px, and
   --ink-700 at 10.02:1 on white (was --ink-500 at 5.92:1). */
.field__hint {
  margin: .45rem 0 0;
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--ink-700);
}

/* The error becomes a small tinted plate so it is findable by shape as well as
   by colour (1.4.1). --danger on --danger-bg = 5.72:1, and the 4px danger rail
   against the white panel = 6.54:1. Vertical padding lives only in the open
   state — padding inside a max-height:0 box would leave a visible strip, the
   same trap DESIGN.md flags for the accordion. */
.field__error {
  padding: 0 .8rem;
  font-size: var(--fs-sm);
  line-height: 1.45;
  border-left: 4px solid transparent;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  transition: max-height var(--transition), margin var(--transition),
    padding var(--transition), background var(--transition);
}

.field.is-invalid .field__error,
.fieldset.is-invalid .field__error {
  max-height: 8rem;
  /* room for the two-line phone/email messages */
  margin-top: .55rem;
  padding: .6rem .8rem;
  background: var(--danger-bg);
  border-left-color: var(--danger);
}

.field__error::before {
  margin-right: .45rem;
  font-weight: 700;
}


/* ---- Service picker & consent -------------------------------------------
   Six 56px targets on a calm white ground. The card border is grouping chrome;
   the control's own boundary is the 24px box below, which carries the 3:1. */
.checkbox-grid {
  gap: .75rem;
}

.checkbox {
  align-items: center;
  gap: .85rem;
  min-height: 3.5rem;
  /* 56px, comfortably over the 44px floor */
  padding: .85rem 1rem;
  border-color: var(--line-strong);
  background: var(--white);
  line-height: 1.4;
  transition: border-color var(--transition), background var(--transition),
    box-shadow var(--transition);
}

.checkbox:hover {
  border-color: var(--ink-500);
  background: var(--off-white);
}

.checkbox:has(input:checked) {
  border-color: var(--teal-600);
  /* 5.83:1 on white */
  background: var(--teal-050);
  /* --ink-900 label on it = 16.62:1 */
  box-shadow: var(--shadow-sm);
}

.checkbox:has(input:focus-visible) {
  outline: 3px solid var(--teal-600);
  outline-offset: 3px;
}

/* The label already carries the ring — drop the inner one so it isn't doubled.
   Nested inside :has(), so a browser without :has() keeps the native ring. */
.checkbox:has(input:focus-visible) input[type="checkbox"] {
  outline: none;
}

/* accent-color gave a ~16px system box. A 24px drawn box with a real tick is
   far easier to hit and to read at arm's length. State stays 100% native. */
.checkbox input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 1.5rem;
  height: 1.5rem;
  margin: 0;
  border: 2px solid var(--line-input);
  /* 3.40:1 on --off-white, 3.62:1 on white */
  border-radius: 7px;
  background: var(--white);
  transition: background-color var(--transition), border-color var(--transition);
}

.checkbox input[type="checkbox"]:checked {
  border-color: var(--teal-600);
  background-color: var(--teal-600);
  /* white tick on it = 5.83:1 */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FFFFFF' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 15px;
}

/* Consent is the last decision before sending — give it weight and its own
   ground so it can't be skimmed past. */
.checkbox--consent {
  align-items: center;
  gap: 1rem;
  padding: 1.05rem 1.15rem;
  background: var(--off-white);
  border-color: var(--line-strong);
  font-weight: 700;
}

.checkbox--consent:has(input:checked) {
  background: var(--teal-050);
  border-color: var(--teal-600);
}

/* §12's `.field.is-invalid input` would tint the consent box red — here that
   is exactly right, so it is restated on the whole row. */
.field.is-invalid .checkbox--consent {
  border-color: var(--danger);
  /* 6.54:1 on white */
  background: var(--danger-bg);
}

/* …but the same rule reaches all six service boxes when the fieldset is
   invalid, turning the group into a wall of red. The outline on the group is
   the message; the individual boxes stay neutral. */
.fieldset.is-invalid .checkbox-grid {
  outline: 2px solid var(--danger);
  outline-offset: 8px;
  border-radius: var(--r-lg);
}

.fieldset.is-invalid .checkbox input[type="checkbox"] {
  border-color: var(--line-input);
  background-color: var(--white);
}

.fieldset.is-invalid .checkbox:has(input:checked) input[type="checkbox"] {
  border-color: var(--teal-600);
  background-color: var(--teal-600);
}


/* ---- Form status ---------------------------------------------------------
   One live region carries three different messages. Colour-coding all of them
   red meant "Sending your referral…" looked like a failure on every successful
   submit. The button's own .is-loading class (set by main.js, and #formStatus
   is its next sibling in both forms) lets CSS tell the pending state apart —
   no JS or markup change needed.
   Empty stays invisible via :not(:empty) rather than display:none, so the
   aria-live region is never removed from the accessibility tree. */
.form__status {
  margin: var(--space-4) 0 0;
  text-align: left;
  line-height: 1.5;
}

.form__status:not(:empty) {
  padding: .85rem 1.05rem;
  border-radius: var(--r-md);
  border-left: 4px solid var(--danger);
  background: var(--danger-bg);
  color: var(--danger);
  /* 5.72:1 on --danger-bg */
}

.form__status.is-success:not(:empty) {
  border-left-color: var(--success);
  background: var(--success-bg);
  color: var(--success);
  /* 5.26:1 on --success-bg */
}

.btn.is-loading~.form__status:not(:empty) {
  border-left-color: var(--teal-600);
  background: var(--off-white);
  color: var(--ink-700);
  /* 9.41:1 on --off-white */
}


/* ---- Submit --------------------------------------------------------------
   The site's gradient CTA idiom, sized as the confident last step: 56px tall,
   pushed clear of the consent row, with a teal glow.
   White text measures 9.85:1 at the plum end and 5.83:1 at the teal end —
   checked against the lightest point the gradient reaches, per DESIGN.md. */
.form .btn[type="submit"] {
  margin-top: var(--space-5);
  min-height: 3.5rem;
  padding: 1.1rem 2rem;
  background: linear-gradient(120deg, var(--plum-700) 0%, var(--teal-600) 100%);
  color: var(--white);
  box-shadow: 0 10px 26px rgba(0, 112, 123, .24), var(--shadow-sm);
  letter-spacing: .01em;
}

.form .btn[type="submit"]:hover {
  background: linear-gradient(120deg, var(--plum-800) 0%, var(--teal-700) 100%);
  color: var(--white);
  /* 12.52:1 / 7.71:1 across the hover ramp */
  box-shadow: 0 14px 32px rgba(0, 112, 123, .30), var(--shadow-sm);
}

.form .btn[type="submit"]:focus-visible {
  outline: 3px solid var(--plum-800);
  /* 12.52:1 on the white panel */
  outline-offset: 3px;
}

/* §4's `.btn.is-loading { opacity: .85 }` faded the button into the white
   panel: white on the resulting #26858F is 4.34:1 — under AA, at the exact
   moment the user most needs to read it. Full opacity on solid --teal-700
   instead: white on it = 7.71:1. The spinner still carries the state. */
.form .btn[type="submit"].is-loading,
.form .btn[type="submit"]:disabled {
  opacity: 1;
  background: var(--teal-700);
  color: var(--white);
  box-shadow: var(--shadow-sm);
  transform: none;
  cursor: progress;
}

/* Plane and spinner at once is two things moving; the spinner is the truthful
   one while sending. */
.form .btn[type="submit"].is-loading i {
  opacity: 0;
  transition: opacity var(--transition);
}


/* ---- Success modal -------------------------------------------------------
   The confirmation summary is the receipt for what was just sent, so the
   values are promoted to --ink-900 (16.95:1 on --off-white, up from --ink-700
   at 9.41:1) and each pair gets a divider so it scans as a list of facts. */
.modal__summary dl {
  gap: 0;
}

.modal__summary dt {
  margin-top: .8rem;
}

.modal__summary dt:first-child {
  margin-top: 0;
}

.modal__summary dd {
  margin: .15rem 0 .8rem;
  padding-bottom: .8rem;
  border-bottom: 1px solid var(--line);
  color: var(--ink-900);
  font-weight: 700;
}

.modal__summary dd:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: 0;
}


/* ---- Reduced motion ------------------------------------------------------
   Nothing above introduces a keyframe animation — only transitions on colour,
   shadow and the error plate's max-height. They are all switched off here
   explicitly rather than relying on §18's global duration override. */
@media (prefers-reduced-motion: reduce) {

  .contact__aside .contact-item,
  .contact__form-wrap,
  .checkbox,
  .checkbox input[type="checkbox"],
  .field__error,
  .form__status,
  input[type="text"],
  input[type="email"],
  input[type="tel"],
  select,
  textarea,
  .form .btn[type="submit"],
  .form .btn[type="submit"].is-loading i {
    transition: none;
  }

  .form .btn[type="submit"]:hover {
    transform: none;
  }
}


/* ---- Forced colours ------------------------------------------------------
   appearance:none checkboxes vanish in Windows high-contrast mode, and the
   gradient submit loses its fill — hand both back to the system. */
@media (forced-colors: active) {
  .checkbox input[type="checkbox"] {
    appearance: auto;
    -webkit-appearance: auto;
    width: 1.35rem;
    height: 1.35rem;
  }

  .form .btn[type="submit"] {
    border-color: currentColor;
  }

  .contact__form-wrap::before {
    display: none;
  }
}


/* ==========================================================================
   RESPONSIVE — the five breakpoints the site already defines
   ========================================================================== */

/* Small desktop: the two panels give back some of the gap before they stack */
@media (max-width: 1080px) {
  .contact__grid {
    grid-template-columns: .9fr 1.1fr;
    gap: clamp(1.25rem, 2.5vw, 2rem);
  }
}

/* Tablet landscape — the grid stacks here.
   §19 already carries `.contact__grid { grid-template-columns: 1fr }` at this
   breakpoint, but the unconditional two-column rule further up this section
   comes later in the file at equal specificity, so it won out and the panels
   never stacked: on a 500px screen the form was squeezed to a 200px column and
   the page scrolled sideways. Restating it here puts it after that rule.
   A stacked sidebar would be a very tall dark column, so its rows re-flow into
   a band instead. The title and the note stay full width. */
@media (max-width: 960px) {
  .contact__grid {
    grid-template-columns: 1fr;
  }

  .contact__aside {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: .75rem;
    align-content: start;
  }

  .contact__aside-title,
  .contact__note {
    grid-column: 1 / -1;
    margin: 0;
  }

  .contact__aside .contact-item {
    margin-inline: 0;
    padding: .85rem;
    border-top: 0;
    border-radius: var(--r-md);
    background: rgba(255, 255, 255, .07);
  }

  .contact__aside .contact-item+.contact-item {
    border-top: 0;
  }

  .contact__note {
    margin-top: var(--space-2);
  }
}

/* Tablet portrait: keep two service columns for as long as they stay readable.
   The aside deliberately keeps the 15rem minimum set at 960px — dropping it to
   13rem here squeezed the band to three ~209px cards, too narrow for the email
   address, so it collapsed to two comfortable ones instead. */
@media (max-width: 860px) {
  .checkbox-grid {
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  }
}

/* Mobile — one column, and every target grows. 56px inputs, 60px checkbox
   rows and a 60px submit: this is the size the form is most often filled in
   at, often one-handed. */
@media (max-width: 620px) {

  .contact__aside,
  .checkbox-grid {
    grid-template-columns: 1fr;
  }

  .contact__form-wrap {
    padding: 1.35rem 1.15rem 1.6rem;
  }

  input[type="text"],
  input[type="email"],
  input[type="tel"],
  select {
    min-height: 3.5rem;
  }

  textarea {
    min-height: 8rem;
  }

  .checkbox {
    min-height: 3.75rem;
  }

  .checkbox input[type="checkbox"] {
    width: 1.6rem;
    height: 1.6rem;
  }

  .field-row {
    gap: var(--space-3);
  }

  .form .btn[type="submit"] {
    min-height: 3.75rem;
    margin-top: var(--space-4);
  }

  /* The fieldset outline sits 8px outside the grid; on a narrow panel that
     collides with the padding, so it tucks in. */
  .fieldset.is-invalid .checkbox-grid {
    outline-offset: 5px;
  }
}

/* Very small phones: reclaim horizontal room without shrinking any target */
@media (max-width: 400px) {
  .contact__form-wrap {
    padding: 1.15rem .95rem 1.4rem;
  }

  .contact__aside {
    padding: 1.25rem 1.1rem;
  }

  .checkbox {
    padding: .75rem .8rem;
    gap: .7rem;
  }

  .checkbox--consent {
    padding: .9rem .85rem;
  }

  input[type="text"],
  input[type="email"],
  input[type="tel"],
  select,
  textarea {
    padding-inline: .9rem;
  }

  select {
    padding-right: 2.6rem;
    background-position: right .9rem center;
  }

  .field.is-valid input[type="text"],
  .field.is-valid input[type="email"],
  .field.is-valid input[type="tel"] {
    padding-right: 2.6rem;
    background-position: right .9rem center;
  }
}


/* ---------- NAVIGATION, FOOTER & CHROME ---------- */

/* ==========================================================================
   21. CHROME REFRESH — header, nav, breadcrumb, footer, mobile bar
     Visual only. Appended after §20 so equal-specificity rules win; every
     mechanism from §5 / §13 / §17 / §19 is preserved deliberately:
       · z-index ladder untouched — header 100, backdrop 105, menu 110, toggle 120
       · .nav__list keeps align-items: stretch so the dropdown anchors at
         top: 100% with no hover gap for the pointer to fall through
       · <=860px: .nav__list > li stays display:block and
         .nav__list > li.nav__item--has-menu stays a 2-column grid
       · .to-top keeps its opacity/transform/pointer-events reveal — no `hidden`
       · no backdrop-filter or transform lands on .site-header or .nav below
         861px, because either would make them the containing block for the
         fixed .nav__menu drawer and the fixed .nav-backdrop
   ========================================================================== */

/* ---- 21.1 Chrome tokens ---------------------------------------------------
   The footer greys already in the file are promoted to tokens so nothing here
   is a loose hex. Measured ratios are on the surface each one actually sits on.
   --------------------------------------------------------------------------- */
:root {
  /* Translucent surfaces. Both are opaque enough that the text on them clears
     AA even when the worst-case backdrop (--plum-900) sits behind the blur. */
  --glass-panel: rgba(255, 255, 255, .93);
  /* over --plum-900 → #F0EEF2:
                                               plum-800 10.9:1, ink-500 5.1:1,
                                               teal-600 5.1:1 */
  --glass-bar: rgba(255, 255, 255, .86);
  /* over --plum-900 → #E1DDE4:
                                               plum-800 9.3:1, plum-600 5.5:1 */

  /* Hairlines for dark chrome (topbar / footer). --on-dark-edge is the one used
     on interactive edges: 3.2:1 against --plum-900, clearing the 3:1 UI floor. */
  --on-dark-line: rgba(255, 255, 255, .12);
  --on-dark-edge: rgba(255, 255, 255, .36);
  --on-dark-fill: rgba(255, 255, 255, .08);

  /* Footer type ramp — same three values §13 already used, now named.
     On --plum-900: 10.4:1 / 7.5:1 / 5.5:1. */
  --footer-text: #CFC2DE;
  --footer-muted: #B2A3C4;
  --footer-faint: #9A89AE;

  /* One deeper shadow for the large floating chrome panels */
  --shadow-panel: 0 26px 56px rgba(38, 9, 63, .18), 0 3px 10px rgba(38, 9, 63, .09);
}


/* ---- 21.2 Skip link -------------------------------------------------------
   Same slide-from-above mechanism, just given a real card edge so it doesn't
   read as an accident when it appears. --plum-800 on white text = 12.5:1.
   --------------------------------------------------------------------------- */
.skip-link {
  padding: .9rem 1.6rem;
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  font-size: var(--fs-sm);
  letter-spacing: .01em;
  box-shadow: var(--shadow-panel);
}

.skip-link:focus-visible {
  outline-offset: -6px;
}


/* ---- 21.3 Header shell ----------------------------------------------------
   The header itself stops painting; .topbar and .nav each paint their own
   ground so the two rows can take different surfaces and still read as one
   stacked unit. The white ground moves to .nav, which is what lets the scrolled
   state swap it for glass.
   --------------------------------------------------------------------------- */
.site-header {
  background: transparent;
  border-bottom: 0;
  transition: box-shadow var(--transition);
}

.nav {
  background: var(--white);
  border-bottom: 1px solid var(--line);
  transition: background var(--transition), border-color var(--transition);
}

.site-header.is-stuck {
  box-shadow: 0 10px 30px rgba(38, 9, 63, .10);
}

.nav__inner {
  /* Taller resting row — the extra air is most of what separates a considered
     header from a default one. `gap` is deliberately left alone: between 861
     and 960px the link row plus CTA already runs close to the container edge. */
  min-height: 84px;
  transition: min-height var(--transition);
}

/* Scrolled state — desktop only.
   Condensing on phones would reflow the logo under the thumb mid-scroll, and
   backdrop-filter below 861px would break the fixed drawer's containing block,
   so the whole scrolled treatment is gated at 861px and up. */
@media (min-width: 861px) {
  .site-header.is-stuck .nav {
    background: var(--glass-bar);
    -webkit-backdrop-filter: blur(16px) saturate(150%);
    backdrop-filter: blur(16px) saturate(150%);
    border-bottom-color: rgba(229, 222, 236, .7);
  }

  .site-header.is-stuck .nav__inner {
    min-height: 78px;
  }

  .site-header.is-stuck .brand__logo {
    height: 60px;
  }

  .site-header.is-stuck .topbar__inner {
    padding-block: .3rem;
  }
}


/* ---- 21.4 Topbar ----------------------------------------------------------
   A flat slab reads as a strip bolted on top of the nav; a shallow plum-900 →
   plum-800 rake makes it the dark shoulder of one object. The gradient stops at
   --plum-800 on purpose: anything lighter drops the teal accents under 4.5:1.
   --------------------------------------------------------------------------- */
.topbar {
  /* Mid lavender strip easing toward a hint of the brand teal — clearly its
     own band above the white nav without the weight of the old dark slab.
     --plum-800 text on the darkest stop (#D8C5EB) = 8.1:1. */
  background: linear-gradient(100deg, #D8C5EB 0%, #E2D4F1 55%, #CDE8EA 100%);
  color: var(--plum-800);
  border-bottom: 1px solid rgba(72, 24, 120, .14);
  /* Stays at --fs-sm: this audience includes older readers and the phone
     number is the single most-used thing in the chrome. */
  font-size: var(--fs-sm);
  letter-spacing: .01em;
}

.topbar__inner {
  gap: .25rem 1.5rem;
  padding-block: .45rem;
  transition: padding-block var(--transition);
}

.topbar__item {
  position: relative;
  gap: .55rem;
  padding-block: .15rem;
  font-weight: 700;
  transition: color var(--transition);
}

/* Icons get a small chip so the row has texture without extra weight.
   --teal-400 on the chip (#5A2F86) = 3.8:1 — decorative, but clears 3:1 anyway. */
.topbar__item i {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .6);
  color: var(--teal-600);                /* 5.2:1 on the white chip */
  font-size: .72em;
  transition: background var(--transition), color var(--transition);
}

/* Hover resolves to white + a hairline rule rather than tinting the label:
   white is 12.5:1 on --plum-800 where --teal-400 was a marginal 4.9:1. */
.topbar__item::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: currentColor;
  opacity: 0;
  transition: opacity var(--transition);
}

.topbar__item:hover {
  color: var(--teal-700);
}

.topbar__item:hover::after {
  opacity: .55;
}

.topbar__item:hover i {
  background: var(--teal-600);
  color: var(--white);
}

.topbar__item--muted {
  color: var(--ink-700);
}

/* 6.4:1 on --plum-800 */
.topbar__item:focus-visible {
  outline-offset: 2px;
}


/* ---- 21.5 Brand & hamburger ----------------------------------------------- */
.brand {
  border-radius: var(--r-md);
}

.brand:focus-visible {
  outline-offset: 4px;
}

.brand__logo {
  transition: height var(--transition);
}

/* The toggle becomes a proper card control instead of an outlined box.
   Bar height (2.5px) and gap (5px) are untouched — the open-state X in §5
   translates by exactly 7.5px and breaks if either changes. */
.nav__toggle {
  width: 48px;
  height: 48px;
  background: var(--white);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  transition: background var(--transition), border-color var(--transition),
    box-shadow var(--transition);
}

.nav__toggle:hover {
  border-color: var(--plum-600);
  box-shadow: var(--shadow-md);
}

.nav__toggle[aria-expanded="true"] {
  background: var(--teal-050);
  border-color: var(--teal-500);
}

/* Shorter middle bar — a small piece of character that survives the morph,
   since bar 2 is the one that fades out when the X forms. */
.nav__bar:nth-child(2) {
  width: 15px;
}


/* ---- 21.6 Nav links -------------------------------------------------------
   The §5 underline mechanism is kept exactly (scaleX from the left, one
   transition) and only re-proportioned: 2px, closer to the baseline, and
   carrying the site's plum → teal gradient instead of flat teal.
   --------------------------------------------------------------------------- */
.nav__list {
  /* Restated on purpose — the dropdown anchors on this. */
  align-items: stretch;
  gap: .15rem;
}

.nav__link {
  padding: .65rem .95rem;
  border-radius: var(--r-pill);
  font-size: var(--fs-sm);
  letter-spacing: .005em;
  transition: background var(--transition), color var(--transition);
}

.nav__link::after {
  left: .95rem;
  right: .95rem;
  bottom: .3rem;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--plum-600), var(--teal-500));
}

.nav__link:hover {
  background: var(--teal-050);
  color: var(--teal-600);
}

.nav__link.is-active {
  color: var(--teal-600);
}

.nav__link:focus-visible {
  outline-offset: 2px;
}

.nav__item--has-menu .nav__link {
  padding-right: .4rem;
}

.nav__submenu-toggle {
  width: 28px;
  height: 28px;
  border-radius: var(--r-pill);
  color: var(--plum-600);
  font-size: .72rem;
}

.nav__submenu-toggle:focus-visible {
  outline-offset: 2px;
}


/* ---- 21.7 Services dropdown -----------------------------------------------
   Flush at top: 100% — no float, no gap, because a gap would drop the pointer
   onto the page behind and fire the mouseleave that closes the panel. It reads
   instead as a drawer sliding out of the header's own bottom edge: square top
   corners, generous bottom radius, and a gradient seam along the join.
   --------------------------------------------------------------------------- */
@media (min-width: 861px) {
  .nav__dropdown {
    left: -.75rem;
    width: 380px;
    padding: .55rem;
    background: var(--glass-panel);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
    border: 1px solid var(--line);
    border-top: 0;
    border-radius: 0 0 var(--r-lg) var(--r-lg);
    box-shadow: var(--shadow-panel);
    overflow: hidden;
  }

  /* The seam that ties the panel back to the header edge */
  .nav__dropdown::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 2px;
    background: linear-gradient(90deg, var(--plum-700), var(--teal-500));
  }

  .nav__dropdown ul {
    gap: .15rem;
  }

  .nav__dropdown a {
    align-items: center;
    gap: .85rem;
    padding: .7rem .75rem;
    border-radius: var(--r-md);
    /* Colour-only hover feedback — no second stagger to fight the §5 one. */
    transition: background var(--transition), color var(--transition),
      box-shadow var(--transition);
  }

  /* Icon chip: --teal-600 on --teal-050 = 5.4:1 */
  .nav__dropdown a i {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    margin-top: 0;
    border-radius: var(--r-sm);
    background: var(--teal-050);
    color: var(--teal-600);
    font-size: .95rem;
    transition: background var(--transition), color var(--transition);
  }

  .nav__dropdown a:hover,
  .nav__dropdown a:focus-visible {
    background: var(--teal-050);
    box-shadow: inset 3px 0 0 var(--teal-500);
  }

  .nav__dropdown a:hover i,
  .nav__dropdown a:focus-visible i {
    background: var(--teal-600);
    /* white icon on it = 5.8:1 */
    color: var(--white);
  }

  .nav__dropdown a small {
    margin-top: .1rem;
  }

  /* The "view everything" row reads as the panel's foot, not a sixth service */
  .nav__dropdown li:last-child a {
    margin-top: .35rem;
    padding-block: .8rem;
    border-top: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--teal-050);
    color: var(--teal-600);
    /* 5.4:1 on --teal-050 */
    font-size: var(--fs-xs);
    letter-spacing: .04em;
    text-transform: uppercase;
  }

  /* CSS-drawn chevron rather than a Font Awesome pseudo-glyph, which some
     screen readers announce as a private-use character. */
  .nav__dropdown li:last-child a::after {
    content: '';
    width: 7px;
    height: 7px;
    margin-left: auto;
    border: 2px solid currentColor;
    border-width: 2px 2px 0 0;
    border-radius: 1px;
    transform: rotate(45deg);
    transition: transform var(--transition);
  }

  .nav__dropdown li:last-child a:hover::after {
    transform: rotate(45deg) translate(2px, -2px);
  }

  .nav__dropdown li:last-child a:hover {
    box-shadow: none;
  }
}

.nav__dropdown a:focus-visible {
  outline-offset: -3px;
}


/* ---- 21.8 Mobile drawer (<=860px) -----------------------------------------
   Same fixed panel, same transform + visibility transition, same stagger.
   Only the surface changes: a rounded glass card with the toggle's rail down
   its edge. backdrop-filter is safe *here* — the drawer has no fixed children.
   --------------------------------------------------------------------------- */
@media (max-width: 860px) {
  .topbar__inner {
    justify-content: center;
  }

  /* 44px minimum touch height for the two tel:/mailto: links */
  .topbar__item {
    min-height: 44px;
    padding-inline: .2rem;
  }

  .topbar__inner {
    padding-block: .1rem;
  }

  .nav__menu {
    width: min(90vw, 380px);
    padding: 6rem var(--space-4) calc(var(--space-5) + env(safe-area-inset-bottom, 0px));
    background: var(--glass-panel);
    -webkit-backdrop-filter: blur(20px) saturate(140%);
    backdrop-filter: blur(20px) saturate(140%);
    border-left: 1px solid var(--line);
    border-radius: var(--r-xl) 0 0 var(--r-xl);
    box-shadow: var(--shadow-panel);
  }

  .nav__list {
    gap: 0;
  }

  /* Hairlines between rows instead of a boxed border on every link */
  .nav__link {
    padding: .95rem .6rem;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    font-size: var(--fs-md);
    /* Outline drawn inside — the drawer is a scroll container and would clip
       an outset ring at its edges. */
    outline-offset: -3px;
  }

  .nav__link.is-active {
    background: transparent;
    color: var(--teal-600);
    box-shadow: inset 3px 0 0 var(--teal-500);
  }

  .nav__link:hover {
    background: var(--teal-050);
  }

  /* Grid restated at the same specificity as §19 so the chevron stays on the
     row instead of dropping to its own line. */
  .nav__list>li.nav__item--has-menu {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    border-bottom: 1px solid var(--line);
  }

  .nav__item--has-menu .nav__link {
    border-bottom: 0;
    padding-right: .6rem;
  }

  .nav__list>li.nav__item--has-menu:has(.nav__link.is-active) {
    background: transparent;
    box-shadow: inset 3px 0 0 var(--teal-500);
  }

  .nav__list>li.nav__item--has-menu:has(.nav__link.is-active) .nav__link {
    box-shadow: none;
  }

  .nav__submenu-toggle {
    width: 44px;
    height: 44px;
    border-left: 1px solid var(--line);
    border-radius: 0;
    color: var(--plum-600);
    font-size: 1rem;
  }

  .nav__submenu-toggle:focus-visible {
    outline-offset: -3px;
  }

  /* Sub-list reads as an indented branch of the row above it */
  .nav__dropdown {
    background: transparent;
  }

  .nav__item--has-menu.is-open .nav__dropdown {
    padding: .35rem 0 .5rem .85rem;
    margin-left: .6rem;
    border-left: 2px solid var(--teal-100);
  }

  .nav__dropdown a {
    align-items: center;
    gap: .7rem;
    padding: .7rem .6rem;
    min-height: 44px;
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
    outline-offset: -3px;
  }

  .nav__dropdown a i {
    width: 1.5rem;
    margin-top: 0;
    color: var(--teal-600);
  }

  .nav__dropdown li:last-child a {
    margin-top: .2rem;
    border-top: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--teal-600);
    font-weight: 800;
  }

  /* Backdrop: keep the §19 fade-in, add a shallow blur so the page behind
     recedes instead of merely darkening. */
  .nav-backdrop {
    background: linear-gradient(180deg, rgba(38, 9, 63, .42), rgba(38, 9, 63, .58));
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
  }
}


/* ---- 21.9 Breadcrumb ------------------------------------------------------
   Was a white strip with a hard rule under it, sitting between a white header
   and a dark page hero. Now it fades from white into the page ground and drops
   the rule entirely — one less horizontal line stacked against the header's.
   --------------------------------------------------------------------------- */
.breadcrumb {
  padding-block: var(--space-3);
  background: linear-gradient(180deg, var(--white), var(--off-white));
  border-bottom: 0;
  font-size: var(--fs-xs);
}

.breadcrumb ol {
  gap: .3rem .6rem;
}

.breadcrumb li {
  color: var(--ink-500);
}

/* 5.6:1 on --off-white */
.breadcrumb li+li::before {
  color: var(--ink-500);
  font-size: .8em;
  opacity: .7;
}

.breadcrumb a {
  color: var(--ink-700);
  /* 9.4:1 on --off-white */
  padding-block: .2rem;
  border-radius: 4px;
  text-decoration: none;
}

.breadcrumb a:hover {
  color: var(--teal-600);
  text-decoration: underline;
}

.breadcrumb [aria-current="page"] {
  color: var(--plum-800);
  /* 11.8:1 on --off-white */
  font-weight: 800;
}


/* ---- 21.11 Back-to-top ----------------------------------------------------
   Reveal mechanism untouched: opacity + transform + pointer-events, driven by
   .is-visible. Only the surface is restated.
   --------------------------------------------------------------------------- */
.to-top {
  width: 52px;
  height: 52px;
  border: 1px solid rgba(255, 255, 255, .18);
  background: var(--plum-800);
  color: var(--white);
  /* 12.5:1 */
  box-shadow: 0 14px 30px rgba(38, 9, 63, .28);
}

.to-top.is-visible:hover {
  background: var(--teal-600);
}

/* white = 5.8:1 */
.to-top:focus-visible {
  outline-offset: 4px;
}


/* ---- 21.12 Mobile action bar ----------------------------------------------
   Already the site's glass reference. Pushed a little further — heavier blur,
   a lifted lip, and a ghost button whose edge is actually visible on glass
   (--line-strong was 1.2:1 against it; --plum-600 is 5.5:1).
   --------------------------------------------------------------------------- */
.mobile-bar {
  padding: .65rem .8rem calc(.65rem + env(safe-area-inset-bottom, 0px));
  background: var(--glass-bar);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  backdrop-filter: blur(18px) saturate(150%);
  border-top: 1px solid var(--line);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  box-shadow: 0 -8px 26px rgba(38, 9, 63, .14);
}

.mobile-bar .btn {
  min-height: 46px;
  padding: .75rem 1rem;
  border-radius: var(--r-pill);
}

.mobile-bar .btn--ghost {
  background: rgba(255, 255, 255, .7);
  border-color: var(--plum-600);
  color: var(--plum-800);
  /* 9.3:1 on the glass */
}

.mobile-bar .btn--ghost:hover {
  background: var(--white);
}


/* ---- 21.13 Responsive tidy-up --------------------------------------------- */
@media (max-width: 620px) {
  .topbar {
    font-size: var(--fs-xs);
  }

  .topbar__inner {
    gap: 0 1rem;
  }

  .breadcrumb {
    padding-block: var(--space-2);
  }

  .to-top {
    width: 46px;
    height: 46px;
  }
}

@media (max-width: 400px) {
  .topbar__item {
    gap: .4rem;
  }

  .nav__menu {
    width: min(94vw, 340px);
    border-radius: var(--r-lg) 0 0 var(--r-lg);
  }
}


/* ---- 21.14 Reduced motion -------------------------------------------------
   §18 already zeroes every duration globally; these kill the *displacement*
   for the transforms in this block, including the footer social lift that §18
   never covered.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {

  .nav__inner,
  .brand__logo,
  .topbar__inner,
  .nav {
    transition: none;
  }

  .nav__dropdown li:last-child a:hover::after {
    transform: none;
  }

  .nav__dropdown li:last-child a::after {
    transform: rotate(45deg);
  }

  .topbar__item::after {
    transition: none;
  }
}


/* ==========================================================================
   22. ACCESSIBILITY TOOLBAR
   A self-contained reader-preference panel: text size, high contrast,
   underlined links and a plain readable typeface. Preferences are stored on
   the visitor's own device by main.js and re-applied by a tiny inline script
   in each page's <head>, so a choice survives navigation without a flash of
   the default styling.

   State lives on <html> — `data-a11y-scale` for the text step, and one class
   per toggle — so every rule below can be written as a plain descendant
   selector and nothing here depends on the DOM order of the widget itself.
   --------------------------------------------------------------------------- */

:root {
  /* Plain, wide-set faces that stay legible at small sizes — deliberately not
     the brand pairing, since that is the thing being opted out of. */
  --font-readable: Verdana, Tahoma, 'DejaVu Sans', 'Segoe UI', system-ui, sans-serif;
  /* Amber on black clears 15:1 and is the convention for high-contrast links */
  --hc-link: #FFE600;
}

/* ---- 22.1 Text resizing ---------------------------------------------------
   Scaling the root font size carries the whole rem-based type and spacing
   scale with it, which is why the site was built on rem in the first place.
   The step is a single number, `--a11y-zoom`, written inline on <html> by
   main.js (and by the head script before first paint), so any value in the
   80–150% range applies live with no per-step rule to keep in sync.
   --------------------------------------------------------------------------- */
html {
  font-size: calc(100% * var(--a11y-zoom, 1));
}

/* ---- 22.2 Underlined links ----------------------------------------------- */
html.a11y-underline a {
  text-decoration: underline !important;
  text-underline-offset: .18em;
}

/* ---- 22.3 Readable typeface -----------------------------------------------
   Font Awesome draws glyphs from its own families, so the icon classes have to
   be handed back afterwards or every icon turns into a stray letter.
   --------------------------------------------------------------------------- */
html.a11y-readable body,
html.a11y-readable body * {
  font-family: var(--font-readable) !important;
  letter-spacing: .01em;
}

html.a11y-readable .fa,
html.a11y-readable .fas,
html.a11y-readable .far,
html.a11y-readable .fa-solid,
html.a11y-readable .fa-regular {
  font-family: 'Font Awesome 6 Free' !important;
}

html.a11y-readable .fab,
html.a11y-readable .fa-brands {
  font-family: 'Font Awesome 6 Brands' !important;
}

/* ---- 22.4 High contrast ---------------------------------------------------
   Black ground, white text, amber links — the pattern people who need it
   already recognise from government and council sites. The blanket rule strips
   every decorative fill, gradient and shadow; the rules after it reinstate the
   three things that must stay distinguishable: links, controls and the panel.
   --------------------------------------------------------------------------- */
html.a11y-contrast {
  background: #000 !important;
}

html.a11y-contrast body {
  background: #000 !important;
  color: #FFF !important;
}

html.a11y-contrast body * {
  background-color: transparent !important;
  background-image: none !important;
  color: #FFF !important;
  border-color: #FFF !important;
  box-shadow: none !important;
  text-shadow: none !important;
  -webkit-text-fill-color: currentColor !important;
}

html.a11y-contrast a,
html.a11y-contrast a * {
  color: var(--hc-link) !important;
  text-decoration: underline !important;
}

html.a11y-contrast .btn,
html.a11y-contrast button,
html.a11y-contrast input,
html.a11y-contrast select,
html.a11y-contrast textarea {
  background: #000 !important;
  color: var(--hc-link) !important;
  border: 2px solid var(--hc-link) !important;
}

html.a11y-contrast ::placeholder {
  color: #CFCFCF !important;
}

/* The blanket rule above strips every background image, which would also take
   the custom checkbox tick and the select chevron with it — the two places a
   background image is carrying actual state rather than decoration. Both are
   redrawn here in the amber used for links. */
html.a11y-contrast .checkbox input[type="checkbox"]:checked {
  background-color: #000 !important;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FFE600' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: center !important;
  background-size: 15px !important;
}

html.a11y-contrast select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FFE600' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: right 1rem center !important;
  background-size: 18px !important;
}

html.a11y-contrast :focus-visible {
  outline: 3px solid var(--hc-link) !important;
  outline-offset: 2px;
}

/* Photographs stay, but calmed down so white text near them keeps its edge */
html.a11y-contrast img,
html.a11y-contrast video {
  filter: grayscale(1) contrast(1.15);
}

/* Icon chips lose their fill above; a hairline keeps them from floating */
html.a11y-contrast .sf__ico,
html.a11y-contrast .contact-item__icon {
  border: 1px solid #FFF !important;
}

/* ---- 22.5 The launcher ---------------------------------------------------
   The control lives in the topbar, hard left, with the phone and email staying
   hard right — `margin-right: auto` on a flex-end row does the whole job and
   leaves the widest possible gap between the two groups. Keeping it out of the
   nav row also gives the logo lockup and the primary links their full width
   back, so none of the nav's own spacing has to be traded away for it.
   --------------------------------------------------------------------------- */

/* The panel hangs off the topbar container, not off the button, so it inherits
   the container's gutter and can never run past the viewport edge. */
.topbar__inner {
  position: relative;
}

/* Both reader chips live in one group pinned hard left, in line with the
   logo below; its auto margin pushes the contact links hard right. */
.topbar__tools {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-right: auto;
}

.a11y,
.lang {
  display: inline-flex;
}

.a11y__toggle {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  /* Tighter on the icon side so the chip sits inside the pill, not beside it */
  padding: .2rem .85rem .2rem .25rem;
  border: 1px solid rgba(72, 24, 120, .18);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .7);
  color: var(--plum-800);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: .01em;
  line-height: 1.4;
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}

/* The same icon chip the phone and email items carry, so the row reads as one set */
.a11y__toggle i {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: var(--r-pill);
  background: var(--teal-050);
  color: var(--teal-600);
  font-size: .95em;
  transition: background var(--transition), color var(--transition);
}

.a11y__toggle:hover {
  background: var(--white);
  border-color: var(--teal-500);
  color: var(--teal-700);
}

.a11y__toggle:hover i {
  background: var(--teal-600);
  color: var(--white);
}

.a11y__toggle[aria-expanded="true"] {
  background: var(--teal-600);
  border-color: var(--teal-600);
  color: var(--white);
}

.a11y__toggle[aria-expanded="true"] i {
  background: rgba(255, 255, 255, .18);
  color: var(--white);
}

/* ---- 22.6 Shared popover --------------------------------------------------
   The accessibility tools and the language picker share one card style so
   the two chips in the topbar open into the same kind of thing. On desktop
   each card hangs under its own chip; on phones (§22.9) both span the
   topbar's gutters instead.
   --------------------------------------------------------------------------- */
.a11y,
.lang {
  position: relative;
}

.kc-caret {
  width: auto !important;
  height: auto !important;
  background: none !important;
  font-size: .62em !important;
  color: inherit !important;
  opacity: .75;
  margin-left: -.1rem;
  transition: transform var(--transition);
}

.a11y__toggle[aria-expanded="true"] .kc-caret {
  transform: rotate(180deg);
}

.kc-pop {
  position: absolute;
  z-index: 130;
  /* above the nav toggle (120) — see §4600 ladder */
  top: calc(100% + .55rem);
  left: 0;
  width: 21.5rem;
  max-width: calc(100vw - 2 * var(--gutter));
  padding: .5rem;
  border: 1px solid rgba(72, 24, 120, .10);
  border-radius: 18px;
  background: var(--white);
  color: var(--ink-900);
  box-shadow: 0 24px 60px -18px rgba(38, 9, 63, .35), 0 4px 14px rgba(6, 24, 47, .08);
  transform-origin: top left;
  animation: kc-pop-in 160ms cubic-bezier(.2, .8, .2, 1);
}

.kc-pop[hidden] {
  display: none;
}

@keyframes kc-pop-in {
  from {
    opacity: 0;
    transform: translateY(-4px) scale(.98);
  }
}

.kc-pop__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: .75rem;
  padding: .55rem .6rem .7rem;
}

.kc-pop__title {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.05rem;
  font-weight: 800;
  line-height: 1.3;
  color: var(--ink-900);
}

.kc-pop__hint {
  margin: .1rem 0 0;
  font-size: .8rem;
  line-height: 1.4;
  color: var(--ink-500);
}

.kc-pop__reset {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  flex-shrink: 0;
  padding: .3rem .65rem;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--plum-800);
  font: inherit;
  font-size: .82rem;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--transition);
}

.kc-pop__reset:hover {
  background: rgba(72, 24, 120, .08);
}

.kc-pop__reset i {
  font-size: .8em;
}

/* Square icon chip used by every row */
.kc-ico {
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  flex-shrink: 0;
  border-radius: 10px;
  background: var(--teal-050);
  color: var(--teal-600);
  font-size: .9rem;
  transition: background var(--transition), color var(--transition);
}

/* ---- 22.7 Accessibility rows --------------------------------------------- */
.a11y__zoom {
  margin: 0 0 .35rem;
  padding: .6rem .6rem .7rem;
  border-radius: 14px;
  background: var(--off-white);
}

.a11y__zoom-head {
  display: flex;
  align-items: center;
  gap: .7rem;
  font-size: .95rem;
  font-weight: 700;
}

.a11y__zoom-head label {
  flex: 1;
}

.a11y__value {
  min-width: 3.2rem;
  padding: .15rem .5rem;
  border-radius: var(--r-pill);
  background: var(--white);
  border: 1px solid var(--line);
  font-size: .8rem;
  font-weight: 800;
  text-align: center;
  color: var(--teal-600);
  font-variant-numeric: tabular-nums;
}

.a11y__zoom-row {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-top: .6rem;
}

.a11y__step {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--white);
  color: var(--ink-900);
  font-size: .75rem;
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}

.a11y__step:hover {
  background: var(--teal-600);
  border-color: var(--teal-600);
  color: var(--white);
}

.a11y__step[disabled] {
  opacity: .4;
  cursor: not-allowed;
}

.a11y__step[disabled]:hover {
  background: var(--white);
  border-color: var(--line);
  color: var(--ink-900);
}

.a11y__range {
  flex: 1;
  min-width: 0;
  height: 1.5rem;
  accent-color: var(--teal-600);
  cursor: pointer;
}

.a11y__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: .1rem;
}

.a11y__btn {
  width: 100%;
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .5rem .6rem;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--ink-900);
  font: inherit;
  font-size: .95rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background var(--transition);
}

.a11y__btn:hover {
  background: var(--off-white);
}

.a11y__label {
  flex: 1;
}

/* iOS-style switch; the button's aria-pressed is the source of truth */
.a11y__switch {
  position: relative;
  width: 2.5rem;
  height: 1.45rem;
  flex-shrink: 0;
  border-radius: var(--r-pill);
  background: var(--line-strong);
  transition: background var(--transition);
}

.a11y__switch::after {
  content: '';
  position: absolute;
  top: .2rem;
  left: .2rem;
  width: 1.05rem;
  height: 1.05rem;
  border-radius: 50%;
  background: var(--white);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
  transition: transform var(--transition);
}

.a11y__btn[aria-pressed="true"] .a11y__switch {
  background: var(--teal-600);
}

.a11y__btn[aria-pressed="true"] .a11y__switch::after {
  transform: translateX(1.05rem);
}

.a11y__btn[aria-pressed="true"] .kc-ico {
  background: var(--teal-600);
  color: var(--white);
}

/* ---- 22.8 Language picker ------------------------------------------------ */
.lang__icon {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: var(--r-pill);
  background: var(--teal-050);
  color: var(--teal-600);
  overflow: hidden;
  transition: background var(--transition), color var(--transition);
}

.lang__icon i {
  width: auto !important;
  height: auto !important;
  background: none !important;
  color: inherit !important;
}

.lang__icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.lang__toggle:hover .lang__icon {
  background: var(--teal-600);
  color: var(--white);
}

.lang__toggle[aria-expanded="true"] .lang__icon {
  background: rgba(255, 255, 255, .18);
  color: var(--white);
}

.lang__current {
  max-width: 10rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lang__toggle.is-busy .lang__icon {
  animation: kc-spin 1s linear infinite;
}

@keyframes kc-spin {
  to {
    transform: rotate(360deg);
  }
}

.lang__panel {
  width: 20rem;
}

.lang__search-wrap {
  position: relative;
  margin: 0 .25rem .5rem;
}

.lang__search-wrap i {
  position: absolute;
  left: .85rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: .85rem;
  color: var(--ink-500);
  pointer-events: none;
}

.lang__search {
  width: 100%;
  padding: .62rem .8rem .62rem 2.3rem;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--off-white);
  font: inherit;
  font-size: .92rem;
  color: var(--ink-900);
  transition: border-color var(--transition), background var(--transition), box-shadow var(--transition);
}

.lang__search::placeholder {
  color: var(--ink-500);
}

.lang__search:focus {
  outline: none;
  background: var(--white);
  border-color: var(--teal-600);
  box-shadow: 0 0 0 3px rgba(0, 128, 128, .15);
}

.lang__list {
  max-height: min(22rem, 58vh);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 .1rem .15rem;
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}

.lang__list:focus {
  outline: none;
}

.lang__group {
  position: sticky;
  top: 0;
  z-index: 1;
  margin: 0;
  padding: .5rem .6rem .3rem;
  background: var(--white);
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-500);
}

.lang__group:not(:first-child) {
  margin-top: .3rem;
  border-top: 1px solid var(--line);
  padding-top: .65rem;
}

.lang__opt {
  width: 100%;
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .5rem .6rem;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--ink-900);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 120ms ease;
}

.lang__opt:hover,
.lang__opt:focus-visible {
  background: var(--off-white);
  outline: none;
}

.lang__opt:focus-visible {
  box-shadow: inset 0 0 0 2px var(--teal-500);
}

.lang__flag {
  width: 24px;
  height: 18px;
  flex-shrink: 0;
  border-radius: 4px;
  object-fit: cover;
  background: var(--line);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .08);
}

span.lang__flag {
  display: grid;
  place-items: center;
  background: var(--teal-050);
  color: var(--teal-600);
  font-size: .7rem;
  box-shadow: none;
}

.lang__text {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: .45rem;
  overflow: hidden;
}

.lang__native {
  font-size: .95rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lang__en {
  font-size: .8rem;
  color: var(--ink-500);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lang__check {
  display: none;
  font-size: .8rem;
  color: var(--teal-600);
}

.lang__opt[aria-selected="true"] {
  background: var(--teal-050);
}

.lang__opt[aria-selected="true"] .lang__native {
  color: var(--teal-600);
  font-weight: 800;
}

.lang__opt[aria-selected="true"] .lang__check {
  display: block;
}

.lang__opt mark {
  background: rgba(0, 170, 170, .2);
  color: inherit;
  border-radius: 3px;
  padding: 0 1px;
}

.lang__empty {
  padding: 1.6rem .5rem;
  text-align: center;
  font-size: .9rem;
  color: var(--ink-500);
}

/* ---- 22.9 Small screens, contrast & print -------------------------------- */
@media (max-width: 860px) {

  /* The topbar centres and wraps here; give the tools their own full row,
     still flush left, and line the contact links up under them. */
  .topbar__tools {
    flex-basis: 100%;
    margin-right: 0;
  }

  .topbar__inner {
    justify-content: flex-start !important;
  }
}

@media (max-width: 620px) {
  .a11y__toggle {
    padding: .15rem .65rem .15rem .2rem;
    font-size: var(--fs-xs);
  }

  .a11y__toggle>i:first-child,
  .lang__icon {
    width: 22px;
    height: 22px;
  }

  .topbar__tools {
    gap: .35rem;
  }

  .lang__current {
    max-width: 8.5rem;
  }

  .a11y__toggle .kc-caret {
    display: none;
  }

  /* buys the room for the full label */
  /* Anchor to the topbar row so the card runs gutter to gutter */
  .a11y,
  .lang {
    position: static;
  }

  .kc-pop,
  .lang__panel {
    left: var(--gutter);
    right: var(--gutter);
    width: auto;
    max-width: none;
  }

  .lang__list {
    max-height: 55vh;
  }
}

html.a11y-contrast .kc-pop {
  background: #000 !important;
  border: 2px solid var(--hc-link) !important;
}

html.a11y-contrast .kc-pop__title,
html.a11y-contrast .kc-pop__hint,
html.a11y-contrast .lang__group {
  color: #FFF !important;
  background: #000 !important;
}

html.a11y-contrast .a11y__toggle,
html.a11y-contrast .a11y__btn,
html.a11y-contrast .a11y__zoom,
html.a11y-contrast .a11y__step,
html.a11y-contrast .lang__search,
html.a11y-contrast .lang__opt,
html.a11y-contrast .kc-pop__reset {
  background: #000 !important;
  color: var(--hc-link) !important;
  border: 2px solid var(--hc-link) !important;
}

html.a11y-contrast .kc-ico,
html.a11y-contrast .a11y__value {
  background: #000 !important;
  color: var(--hc-link) !important;
  border: 1px solid var(--hc-link) !important;
}

html.a11y-contrast .a11y__switch {
  background: #444 !important;
}

html.a11y-contrast .a11y__btn[aria-pressed="true"] .a11y__switch {
  background: var(--hc-link) !important;
}

html.a11y-contrast .a11y__switch::after {
  background: #FFF !important;
}

html.a11y-contrast .lang__opt[aria-selected="true"],
html.a11y-contrast .lang__opt[aria-selected="true"] *,
html.a11y-contrast .a11y__toggle[aria-expanded="true"] {
  background: var(--hc-link) !important;
  color: #000 !important;
}

@media print {

  .a11y,
  .lang {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {

  .kc-pop,
  .lang__toggle.is-busy .lang__icon {
    animation: none !important;
  }

  .a11y__toggle {
    transition: none;
  }
}

/* Google Translate injects a banner frame, pushes <body> down and adds hover
   tooltips; the picker above replaces all of that UI. */
.skiptranslate iframe,
iframe.goog-te-banner-frame,
.VIpgJd-ZVi9od-ORHb-OEVmcd,
.VIpgJd-ZVi9od-aZ2wEe-wOHMyf,
.VIpgJd-yAWNEb-L7lbkb,
#goog-gt-tt,
.goog-te-balloon-frame {
  display: none !important;
}

body {
  top: 0 !important;
}

.goog-text-highlight,
font[style] {
  background: none !important;
  box-shadow: none !important;
}

/* Desktop nav labels stay on one line; when the row runs out of room
   main.js (fitNav) scales the menu down instead of letting "About Us" or
   "Staff Login" break into two stacked words. */
@media (min-width: 861px) {

  .nav__link,
  .nav__cta {
    white-space: nowrap;
  }

  /* A notch under the body size so seven items sit comfortably in one row */
  .nav__link {
    font-size: .9375rem;
    /* 15px */
    padding: .6rem .8rem;
  }

  .nav__link::after {
    left: .8rem;
    right: .8rem;
  }

  /* Clear air between the tabs so each reads as its own target */
  .nav__list {
    gap: .9rem;
  }

  /* Topbar text matches the nav links (15px) so the two rows read as one set */
  .topbar,
  .topbar .a11y__toggle {
    font-size: .9375rem;
  }
}

/* ==========================================================================
   23. FOOTER
   Four layers, top to bottom: a call-to-action card (the one thing most
   visitors scroll down here for), the link columns, the Acknowledgement of
   Country with both flags, and a slim legal bar. Plum ground with two soft
   glows so it reads as the dark end of the same system as the topbar.
   ========================================================================== */
.sf {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  margin-top: clamp(1rem, 3vw, 2rem);
  padding-top: clamp(2.5rem, 5vw, 4rem);
  background:
    radial-gradient(60rem 30rem at 100% 0%, rgba(18, 180, 184, .14), transparent 60%),
    radial-gradient(50rem 30rem at 0% 100%, rgba(120, 60, 144, .35), transparent 60%),
    var(--plum-900);
  color: var(--footer-text);                           /* 10.4:1 on --plum-900 */
  font-size: .95rem;
}
/* Brand seam along the top edge */
.sf::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 4px;
  background: linear-gradient(90deg, var(--teal-500), var(--brand-pink) 50%, var(--plum-600));
}
.sf a { color: inherit; text-decoration: none; }
.sf ul { list-style: none; margin: 0; padding: 0; }

/* ---- 23.1 CTA card ------------------------------------------------------- */
.sf__cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem 2rem;
  padding: clamp(1.5rem, 3.5vw, 2.25rem) clamp(1.5rem, 4vw, 2.75rem);
  border-radius: 24px;
  background:
    radial-gradient(30rem 14rem at 100% 0%, rgba(255, 255, 255, .16), transparent 70%),
    linear-gradient(120deg, var(--teal-600), #00586A 55%, var(--plum-700));
  box-shadow: 0 24px 48px -24px rgba(0, 0, 0, .6);
  color: var(--white);
}
.sf__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  margin: 0 0 .4rem;
  font-size: .8rem;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #BFF2F3;
}
.sf__eyebrow i { color: #FF9BCB; }
.sf__cta-title {
  margin: 0;
  max-width: 26ch;
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 1.2vw + 1rem, 1.9rem);
  font-weight: 600;
  line-height: 1.2;
  color: var(--white);
}
.sf__cta-actions { display: flex; flex-wrap: wrap; gap: .75rem; flex-shrink: 0; }
.sf__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  min-height: 3rem;
  padding: .7rem 1.4rem;
  border-radius: var(--r-pill);
  font-weight: 800;
  font-size: .95rem;
  white-space: nowrap;
  transition: background var(--transition), color var(--transition), transform var(--transition), box-shadow var(--transition);
}
.sf .sf__btn--solid { background: var(--white); color: var(--plum-800); }
.sf .sf__btn--solid:hover { background: #F3ECFA; transform: translateY(-2px); box-shadow: 0 10px 20px -10px rgba(0, 0, 0, .5); }
.sf__btn--solid i { transition: transform var(--transition); }
.sf__btn--solid:hover i { transform: translateX(3px); }
.sf .sf__btn--ghost { border: 1.5px solid rgba(255, 255, 255, .55); color: var(--white); }
.sf .sf__btn--ghost:hover { background: rgba(255, 255, 255, .12); border-color: var(--white); }

/* ---- 23.2 Columns -------------------------------------------------------- */
.sf__main {
  display: grid;
  grid-template-columns: 1.35fr 1fr 1.25fr 1.35fr;
  gap: 2.5rem clamp(1.5rem, 3vw, 3rem);
  padding-block: clamp(2.5rem, 5vw, 3.5rem);
}
.sf__logo { display: inline-block; border-radius: 16px; }
.sf__logo img {
  display: block;
  width: auto; height: 92px;
  transition: transform 350ms cubic-bezier(.2, .8, .2, 1), filter 350ms ease;
}
.sf__logo:hover img,
.sf__logo:focus-visible img {
  transform: scale(1.05) rotate(-1deg);
  filter: drop-shadow(0 0 14px rgba(18, 180, 184, .55));
}
.sf__about {
  margin: 1rem 0 1.25rem;
  max-width: 34ch;
  line-height: 1.65;
  color: var(--footer-muted);                          /* 7.5:1 */
}
.sf__social { display: flex; gap: .6rem; }
.sf__social a {
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  border: 1px solid var(--on-dark-edge);
  border-radius: 50%;
  color: var(--white);
  transition: background var(--transition), border-color var(--transition), transform var(--transition);
}
.sf__social a:hover { background: var(--teal-600); border-color: var(--teal-600); transform: translateY(-3px); }

.sf__heading {
  position: relative;
  margin: .35rem 0 1.15rem;
  padding-bottom: .7rem;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: .02em;
  color: var(--white);
}
.sf__heading::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 2rem; height: 3px;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--teal-400), var(--brand-pink));
}

.sf__links { display: grid; gap: .55rem; }
.sf__links a {
  position: relative;
  display: inline-block;
  padding-block: .1rem;
  line-height: 1.45;
  transition: color var(--transition), transform var(--transition);
}
.sf__links a::before {
  content: '';
  position: absolute;
  left: -.85rem; top: 50%;
  width: .4rem; height: .4rem;
  border-radius: 50%;
  background: var(--teal-400);
  opacity: 0;
  transform: translateY(-50%) scale(.4);
  transition: opacity var(--transition), transform var(--transition);
}
.sf__links a:hover { color: var(--white); transform: translateX(.6rem); }
.sf__links a:hover::before { opacity: 1; transform: translateY(-50%) scale(1); }

.sf__contact { display: grid; gap: 1rem; }
.sf__contact li { display: flex; align-items: flex-start; gap: .8rem; line-height: 1.45; }
.sf__contact small {
  display: block;
  margin-bottom: .1rem;
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--footer-faint);
}
.sf__contact a { font-weight: 700; color: var(--white); word-break: break-word; }
.sf__contact a:hover { color: var(--teal-400); }
.sf__ico {
  display: grid;
  place-items: center;
  width: 2.5rem; height: 2.5rem;
  flex-shrink: 0;
  border-radius: 12px;
  background: rgba(18, 180, 184, .14);
  color: var(--teal-400);
}
.sf__staff {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin-top: 1.25rem;
  padding: .55rem 1rem;
  border: 1px solid var(--on-dark-edge);
  border-radius: var(--r-pill);
  font-size: .88rem;
  font-weight: 700;
  color: var(--white);
  transition: background var(--transition), border-color var(--transition);
}
.sf__staff i { color: var(--teal-400); }
.sf .sf__staff:hover { background: rgba(255, 255, 255, .08); border-color: var(--teal-400); }

/* ---- 23.3 Acknowledgement of Country ------------------------------------- */
.sf__ack {
  display: flex;
  align-items: center;
  gap: 1.25rem 1.75rem;
  margin-bottom: clamp(1.75rem, 4vw, 2.5rem);
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--on-dark-line);
  border-radius: 18px;
  background: rgba(255, 255, 255, .04);
}
.sf__flags { display: flex; gap: .85rem; flex-shrink: 0; }
.sf__flags img {
  display: block;
  width: 108px; height: 72px;
  object-fit: cover;
  border-radius: 6px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .15), 0 6px 14px rgba(0, 0, 0, .3);
}
/* Hover: the flag lifts, grows a touch and gives one gentle wave */
.sf__flags img {
  transform-origin: left center;
  transition: transform 300ms cubic-bezier(.2, .8, .2, 1), box-shadow 300ms ease;
}
.sf__flags img:hover {
  transform: translateY(-4px) scale(1.08);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .3), 0 14px 26px rgba(0, 0, 0, .45);
  animation: sf-wave 1.1s ease-in-out;
}
@keyframes sf-wave {
  0%   { transform: translateY(0) scale(1) skewY(0); }
  25%  { transform: translateY(-4px) scale(1.08) skewY(-2.5deg); }
  50%  { transform: translateY(-4px) scale(1.08) skewY(2deg); }
  75%  { transform: translateY(-4px) scale(1.08) skewY(-1deg); }
  100% { transform: translateY(-4px) scale(1.08) skewY(0); }
}

.sf__ack-title {
  margin: 0 0 .3rem;
  font-family: var(--font-body);
  font-size: .8rem;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--white);
}
.sf__ack p {
  margin: 0;
  font-size: .88rem;
  line-height: 1.65;
  color: var(--footer-muted);
}

/* ---- 23.4 Legal bar ------------------------------------------------------ */
.sf__bottom { border-top: 1px solid var(--on-dark-line); }
.sf__bottom-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .5rem 1.5rem;
  padding-block: 1.15rem;
  font-size: .85rem;
  color: var(--footer-faint);
}
.sf__bottom p { margin: 0; }
.sf__legal { display: flex; flex-wrap: wrap; gap: .4rem 1.5rem; }
.sf__legal a { color: var(--footer-text); transition: color var(--transition); }
.sf__legal a:hover { color: var(--teal-400); text-decoration: underline; text-underline-offset: 3px; }

/* ---- 23.5 Responsive ----------------------------------------------------- */
@media (max-width: 1080px) {
  .sf__main { grid-template-columns: repeat(3, 1fr); }
  .sf__brand {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem 2rem;
    padding-bottom: 2rem;
    border-bottom: 1px solid var(--on-dark-line);
  }
  .sf__about { margin: 0; flex: 1 1 18rem; }
}
@media (max-width: 860px) {
  .sf__cta { flex-direction: column; align-items: flex-start; }
}
@media (max-width: 760px) {
  .sf__main { grid-template-columns: 1fr 1fr; }
  .sf__main > .sf__col:last-child { grid-column: 1 / -1; }
}
@media (max-width: 620px) {
  .sf__cta-actions, .sf__btn { width: 100%; }
  /* Quick links and services stay side by side; brand and contact span both */
  .sf__main { grid-template-columns: 1fr 1fr; gap: 2rem 1.25rem; }
  .sf__brand { display: block; }
  .sf__links a { font-size: .9rem; }
  .sf__about { margin: 1rem 0 1.25rem; }
  .sf__logo img { height: 80px; }
  .sf__flags img { width: 96px; height: 64px; }
  .sf__links a { display: inline-flex; align-items: center; min-height: 40px; }
  .sf__links { gap: 0; }
  .sf__ack { flex-direction: column; align-items: flex-start; padding: 1.15rem; }
  .sf__bottom-inner { flex-direction: column; align-items: flex-start; }
  .sf__legal a { display: inline-flex; align-items: center; min-height: 40px; }
}

/* ---- 23.6 Contrast, motion & print --------------------------------------- */
html.a11y-contrast .sf,
html.a11y-contrast .sf__cta,
html.a11y-contrast .sf__ack { background: #000 !important; }
html.a11y-contrast .sf__cta,
html.a11y-contrast .sf__ack { border: 2px solid var(--hc-link) !important; }
html.a11y-contrast .sf__btn--solid { background: var(--hc-link) !important; color: #000 !important; }

@media (prefers-reduced-motion: reduce) {
  .sf__flags img:hover { animation: none; }
  .sf__flags img:hover,
  .sf__logo:hover img,
  .sf__logo:focus-visible img,
  .sf__links a:hover,
  .sf__social a:hover,
  .sf__btn--solid:hover,
  .sf__btn--solid:hover i { transform: none; }
}

@media print {
  .sf { background: #fff; color: #000; padding-top: 1rem; }
  .sf::before { display: none; }
  .sf__main { grid-template-columns: 1fr 1fr; gap: 1rem; }
  .sf__heading, .sf__about, .sf__contact a, .sf__contact small,
  .sf__ack-title, .sf__ack p, .sf__bottom-inner, .sf__legal a { color: #000; }
  .sf__logo, .sf__staff { display: none; }
  .sf__ack { border-color: #000; background: none; }
}


/* ==========================================================================
   24. BOOK SUPPORT / CONTACT US TABS
   A two-way segmented control at the top of the form card. The selected tab
   is a solid teal pill; the other reads as a quiet option on a lavender
   track. Panels switch with `hidden`, driven by main.js (§11a).
   ========================================================================== */
.ctabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .35rem;
  margin-bottom: var(--space-4);
  padding: .35rem;
  border-radius: var(--r-pill);
  background: #F1EAF8;
  border: 1px solid var(--line);
}
.ctabs__tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  min-height: 3rem;
  padding: .6rem 1rem;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--plum-800);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 800;
  cursor: pointer;
  /* Land below the sticky header when reached via #book-support */
  scroll-margin-top: 9rem;
  transition: background var(--transition), color var(--transition), box-shadow var(--transition);
}
.ctabs__tab i { color: var(--teal-600); transition: color var(--transition); }
.ctabs__tab:hover { background: rgba(255, 255, 255, .7); }
.ctabs__tab[aria-selected="true"] {
  background: var(--teal-600);
  color: var(--white);
  box-shadow: 0 6px 16px -8px rgba(0, 112, 123, .7);
}
.ctabs__tab[aria-selected="true"] i { color: var(--white); }
.ctabs__tab:focus-visible { outline: 3px solid var(--teal-500); outline-offset: 2px; }

.ctabs__panel[hidden] { display: none; }
.ctabs__panel:not([hidden]) { animation: ctabs-in 220ms ease; }
@keyframes ctabs-in { from { opacity: 0; transform: translateY(6px); } }

@media (max-width: 400px) {
  .ctabs__tab { font-size: .9rem; padding-inline: .5rem; gap: .4rem; }
}
@media (prefers-reduced-motion: reduce) {
  .ctabs__panel:not([hidden]) { animation: none; }
}
html.a11y-contrast .ctabs { background: #000 !important; border: 2px solid var(--hc-link) !important; }
html.a11y-contrast .ctabs__tab[aria-selected="true"],
html.a11y-contrast .ctabs__tab[aria-selected="true"] * { background: var(--hc-link) !important; color: #000 !important; }

/* Once the contact grid stacks, lead with the tabs and form — that is what
   "Book Support" and "Contact" links promise — and let the direct-contact
   card follow underneath. */
@media (max-width: 960px) {
  .contact__form-wrap { order: -1; }
}
