/* ==========================================================================
   Havilah Cottage — component library (SKILL.md §3)
   BEM-lite, single-class specificity, no IDs for styling.
   Every interactive element defines default / hover / focus-visible / active /
   disabled.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Skip link
   -------------------------------------------------------------------------- */

.skip-link {
  position: absolute;
  top: var(--s-2);
  left: var(--s-2);
  z-index: var(--z-skip);
  padding: var(--s-3) var(--s-5);
  background: var(--c-purple-dark);
  color: var(--c-ivory);
  font-weight: var(--fw-bold);
  border-radius: var(--r-sm);
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--dur-fast) var(--ease-out);
}

.skip-link:focus {
  transform: translateY(0);
  color: var(--c-ivory);
}

/* --------------------------------------------------------------------------
   Utility bar — phone + service area (decision P7)
   -------------------------------------------------------------------------- */

.utility-bar {
  background: var(--g-purple-deep);
  color: var(--c-ivory);
  font-size: var(--fs-sm);
}

/* A slim strip: it sits above the header, so every pixel here pushes the hero
   down. Body leading is relaxed to a tight line so the row stays on one line at
   phone widths; it still wraps rather than overflowing below ~330px. */
.utility-bar__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--s-4);
  align-items: center;
  justify-content: center;
  padding-block: var(--s-1);
  text-align: center;
}

.utility-bar__item {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  /* These are <p>s, so the global `p + p` margin applies and would push the
     phone item down a row's worth. Spacing here is the flex gap's job. */
  margin: 0;
  max-width: none;
  line-height: 1.3;
  color: var(--c-ivory-a85);
}

.utility-bar__item svg {
  flex: none;
  width: 1em;
  height: 1em;
  color: var(--c-gold-light);
}

/* Padding, not extra bar height: it lifts the tel: target back to the 24px
   minimum (WCAG 2.2 AA 2.5.8) inside the tightened line box. */
.utility-bar a {
  display: inline-block;
  padding-block: var(--s-1);
  color: var(--c-ivory);
  font-weight: var(--fw-bold);
  text-decoration: none;
}

.utility-bar a:hover { color: var(--c-gold-light); text-decoration: underline; }

@media (min-width: 64em) {
  .utility-bar__inner { justify-content: space-between; text-align: left; }
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--c-ivory);
  border-bottom: 1px solid var(--c-purple-dark-a12);
  transition: box-shadow var(--dur) var(--ease-out);
}

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

.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-4);
  align-items: center;
  justify-content: space-between;
  padding-block: var(--s-3);
}

.site-header__actions {
  display: flex;
  gap: var(--s-3);
  align-items: center;
}

.brand {
  display: inline-flex;
  flex: none;
  align-items: center;
  text-decoration: none;
}

/* The supplied logo is a stacked lockup (ratio 1.67) where the previous one was
   wide (2.99), so it needs more height to stay legible at the same visual
   weight. Even here the tagline line is tiny — a horizontal variant would serve
   the header far better; see D5. */
.brand img {
  width: auto;
  height: 64px;
}

/* Drawer-only actions, hidden once the nav becomes a desktop bar. */
.nav__actions {
  display: grid;
  gap: var(--s-3);
  margin-top: var(--s-5);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-purple-dark-a12);
}

/* Request care is the primary conversion action (CLAUDE.md §6), so it stays
   visible at every width. Below 40em the logo shrinks, the gaps tighten and
   Menu becomes icon-only, so logo + CTA + Menu fit one line down to 320px.
   These overrides come after the base rules above — at equal specificity the
   later rule wins, and putting them first would silently do nothing. */
@media (max-width: 39.999em) {
  .site-header__inner { gap: var(--s-2); }
  .site-header__actions { gap: var(--s-2); }
  .brand img { height: 52px; }
  .header__cta { padding-inline: var(--s-4); }
  .nav-toggle { padding-inline: var(--s-3); gap: 0; }

  /* Hidden from sight, kept for the accessible name. */
  .nav-toggle__label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

@media (min-width: 64em) {
  /* Desktop order: brand · nav · Request care */
  .site-header__inner { flex-wrap: nowrap; }
  .site-nav { order: 2; margin-left: auto; }
  .site-header__actions { order: 3; }
  .header__cta { min-height: 48px; padding: var(--s-3) var(--s-6); font-size: var(--fs-base); }
  .nav__actions { display: none; }
  .brand img { height: 80px; }
}

/* --- Primary nav --------------------------------------------------------- */

/* Stacked inside the drawer; a row from 64em. */
.nav {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  gap: var(--s-1);
}

.nav__link {
  display: block;
  padding: var(--s-3) var(--s-3);
  color: var(--c-purple-dark);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  text-decoration: none;
  border-radius: var(--r-sm);
  white-space: nowrap;
}

.nav__link:hover {
  background: var(--c-lavender);
  color: var(--c-purple-medium);
}

.nav__link[aria-current="page"] {
  color: var(--c-purple-dark);
  box-shadow: inset 0 -3px 0 var(--c-gold-dark);
}

/* --- Services dropdown (decision P8) -------------------------------------
   The link and the toggle are separate controls: the link always goes to the
   services overview, the toggle only opens the submenu. Without JS the toggle
   is [hidden] and the submenu sits inline, so nothing is dead and nothing
   floats over the page.
   ------------------------------------------------------------------------ */

.nav__item--has-menu {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  min-height: 34px;
  padding: var(--s-2);
  background: none;
  border: 0;
  color: var(--c-purple-dark);
  border-radius: var(--r-sm);
  cursor: pointer;
}

.nav__toggle[hidden] { display: none; }

.nav__toggle:hover { background: var(--c-lavender); color: var(--c-purple-medium); }

.nav__toggle svg {
  width: .8em;
  height: .8em;
  transition: transform var(--dur-fast) var(--ease-out);
}

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

.nav__menu {
  display: grid;
  gap: var(--s-1);
  width: 100%;
  padding: var(--s-3) 0 var(--s-3) var(--s-5);
}

.nav__menu[hidden] { display: none; }

.nav__menu a {
  display: block;
  padding: var(--s-2) var(--s-3);
  color: var(--c-charcoal);
  font-size: var(--fs-sm);
  text-decoration: none;
  border-radius: var(--r-sm);
}

.nav__menu a:hover { background: var(--c-lavender); color: var(--c-purple-dark); }

/* Only float the submenu when JS can close it again. Without JS it stays in
   flow, which makes the header taller but never covers the page. */
@media (min-width: 64em) {
  .nav__menu {
    position: absolute;
    top: calc(100% + var(--s-2));
    left: 0;
    z-index: 1;
    width: auto;
    min-width: 17rem;
    padding: var(--s-3);
    background: var(--c-white);
    border: 1px solid var(--c-purple-dark-a12);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-lift);
  }
}

/* --- Mobile drawer ------------------------------------------------------- */

.nav-toggle {
  display: inline-flex;
  gap: var(--s-2);
  align-items: center;
  min-height: 48px;
  padding: var(--s-2) var(--s-4);
  background: none;
  border: 1px solid var(--c-purple-dark-a20);
  border-radius: var(--r-pill);
  color: var(--c-purple-dark);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  cursor: pointer;
}

.nav-toggle:hover { background: var(--c-lavender); }

.nav-toggle svg { width: 1.1em; height: 1.1em; }

@media (min-width: 64em) {
  .nav-toggle { display: none; }
}

/* The drawer is the DEFAULT layout, not a JS upgrade. Applying it from a class
   that JavaScript adds would pull the nav out of flow after first paint and
   jump the whole page — worth ~0.6 CLS. The no-JS fallback (an in-flow wrapped
   list) is loaded instead by <noscript> in the page head, which the browser
   also applies before first paint. */

.site-nav {
  position: fixed;
  inset: 0 0 0 auto;
  z-index: var(--z-drawer);
  display: grid;
  align-content: start;
  gap: var(--s-2);
  width: min(22rem, 86vw);
  padding: var(--s-8) var(--s-5) var(--s-6);
  overflow-y: auto;
  background: var(--c-ivory);
  box-shadow: var(--shadow-lift);
  /* visibility (not display) so the drawer can animate, while still leaving the
     accessibility tree and the tab order when closed. */
  visibility: hidden;
  transform: translateX(100%);
  transition: transform var(--dur) var(--ease-out),
              visibility 0s linear var(--dur);
}

.site-nav.is-open {
  visibility: visible;
  transform: translateX(0);
  transition: transform var(--dur) var(--ease-out), visibility 0s;
}

.nav__close {
  position: absolute;
  top: var(--s-4);
  right: var(--s-4);
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  background: none;
  border: 1px solid var(--c-purple-dark-a20);
  border-radius: var(--r-pill);
  color: var(--c-purple-dark);
  cursor: pointer;
}

.nav__close:hover { background: var(--c-lavender); }

.nav__close svg { width: 1.1em; height: 1.1em; }

.nav-backdrop {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-drawer) - 1);
  background: var(--c-purple-dark-a50);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

.nav-backdrop.is-open { opacity: 1; }

.nav-backdrop[hidden] { display: none; }

@media (min-width: 64em) {
  .site-nav {
    position: static;
    width: auto;
    padding: 0;
    overflow: visible;
    visibility: visible;
    background: none;
    box-shadow: none;
    transform: none;
    transition: none;
  }
  .nav { flex-direction: row; }
  .nav__link { font-size: var(--fs-sm); }
  .nav__close { display: none; }
  .nav-backdrop { display: none; }
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  gap: var(--s-2);
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: var(--s-3) var(--s-6);
  border: 2px solid transparent;
  border-radius: var(--r-pill);
  font-family: var(--ff-body);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}

.btn svg { flex: none; width: 1.05em; height: 1.05em; }

.btn:active { transform: translateY(1px); }

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: .55;
  cursor: not-allowed;
  transform: none;
}

.btn--primary {
  background: var(--c-purple-dark);
  border-color: var(--c-purple-dark);
  color: var(--c-ivory);
}

.btn--primary:hover {
  background: var(--c-purple-medium);
  border-color: var(--c-purple-medium);
  color: var(--c-ivory);
}

.btn--secondary {
  background: transparent;
  border-color: var(--c-purple-dark);
  color: var(--c-purple-dark);
}

.btn--secondary:hover {
  background: var(--c-purple-dark);
  color: var(--c-ivory);
}

.btn--on-dark {
  background: var(--c-white);
  border-color: var(--c-white);
  color: var(--c-purple-dark);
}

.btn--on-dark:hover {
  background: var(--c-gold-light);
  border-color: var(--c-gold-light);
  color: var(--c-purple-dark);
}

.btn--ghost-on-dark {
  background: transparent;
  border-color: var(--c-ivory-a70);
  color: var(--c-ivory);
}

.btn--ghost-on-dark:hover {
  background: var(--c-ivory);
  border-color: var(--c-ivory);
  color: var(--c-purple-dark);
}

.btn--sm { min-height: 40px; padding: var(--s-2) var(--s-5); font-size: var(--fs-sm); }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  margin-top: var(--s-6);
}

.btn-row--center { justify-content: center; }

/* --------------------------------------------------------------------------
   The cottage arch (SKILL.md §2.4)
   Reserved for the Request Care form panel and the styleguide demo.
   -------------------------------------------------------------------------- */

.arch {
  position: relative;
  display: block;
  isolation: isolate;
}

.arch img {
  width: 100%;
  border-radius: var(--r-arch);
}

/* Thin gold outline offset behind the photo. z-index keeps it behind: without
   it the outline painted over the photo it was meant to frame. */
.arch::before {
  content: "";
  position: absolute;
  inset: -12px -12px 12px 12px;
  z-index: -1;
  border: 2px solid var(--c-gold-dark);
  border-radius: var(--r-arch);
  pointer-events: none;
}

.arch--on-dark::before { border-color: var(--c-gold-light); }

.arch--sm img,
.arch--sm > * { border-radius: var(--r-arch-sm); }

.arch--sm::before {
  inset: -8px -8px 8px 8px;
  border-radius: var(--r-arch-sm);
}

/* --------------------------------------------------------------------------
   Framed photo — a true rectangle with a thin gold border
   The plain-rectangle alternative to .arch, for photos that should read as
   straightforward editorial imagery rather than carry the cottage motif.
   The border sits on the figure, not the <img>, so the image box keeps the
   exact aspect ratio its width/height attributes declare and contributes
   nothing to layout shift.
   -------------------------------------------------------------------------- */

/* The gold edge is 2px of padding over the gold-gradient background — the same
   geometry the old solid border had — because border-image cannot follow a
   radius and a padding edge can carry a gradient. */
.framed {
  display: block;
  padding: 2px;
  background: var(--g-gold);
}

.framed img {
  display: block;
  width: 100%;
  border-radius: 0;
}

/* --------------------------------------------------------------------------
   The cottage door — the arched panel that frames the Request Care form
   The signature element (SKILL.md §2.4), used once. The arch top is the door;
   the gold edge is two background layers, not border-image, which would
   ignore the radius. The head (h1 + lede) is centred under the arch; the
   padding clears the curve at every width, so text never touches it.
   -------------------------------------------------------------------------- */

.door {
  margin-top: var(--s-6);
  padding: max(4.5rem, calc(var(--r-door-rise) * .5)) var(--s-5) var(--s-6);
  border: 2px solid transparent;
  border-radius: var(--r-door);
  background: linear-gradient(var(--c-white), var(--c-white)) padding-box,
              var(--g-gold) border-box;
  box-shadow: var(--shadow-lift);
}

.door__head {
  margin-bottom: var(--s-6);
  text-align: center;
}

.door__lede { margin: var(--s-4) auto 0; }

@media (min-width: 40em) {
  .door { padding-inline: var(--s-7); padding-bottom: var(--s-7); }
}

/* Windows high-contrast mode drops background images, and with them the gold
   edge; a system-colour border keeps the panel outlined. */
@media (forced-colors: active) {
  .door { border-color: CanvasText; }
}

/* --------------------------------------------------------------------------
   Trust strip (SKILL.md §3) — pinned under the hero
   -------------------------------------------------------------------------- */

/* Two columns on a phone: separator rules between wrapped flex items land in
   arbitrary places, so the grid carries the rhythm instead. */
.trust-strip {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s-3) var(--s-4);
  padding-block: var(--s-5);
  text-align: center;
}

.trust-strip li {
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: none;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: .01em;
}

@media (min-width: 40em) {
  .trust-strip {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s-3) 0;
    padding-block: var(--s-4);
  }

  .trust-strip li { padding-inline: var(--s-5); }

  /* A small gold mark separates items — not a middle-dot string. */
  .trust-strip li + li { border-left: 1px solid var(--c-gold-light-a40); }
}

/* --------------------------------------------------------------------------
   Service tile (services grid) — image with label overlay
   -------------------------------------------------------------------------- */

.tile {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--c-purple-dark);
  box-shadow: var(--shadow-lift);
  transition: transform var(--dur) var(--ease-out);
}

.tile:hover { transform: translateY(-3px); }

.tile__media {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Placeholder for a service whose photo has not been supplied. */
.tile__media--pending {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  padding: var(--s-5);
  background: var(--c-lavender);
  color: var(--c-muted);
  font-size: var(--fs-sm);
  text-align: center;
}

.tile__label {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--s-7) var(--s-5) var(--s-4);
  background: var(--g-tile-label);
  color: var(--c-ivory);
  font-size: var(--fs-h4);
  font-family: var(--ff-head);
  font-weight: var(--fw-head);
}

.tile__label a {
  color: inherit;
  text-decoration: none;
}

/* Stretched link: the whole tile is clickable, one tab stop. */
.tile__label a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.tile:focus-within {
  outline: var(--focus-w) solid var(--focus-color);
  outline-offset: var(--focus-offset);
}

.tile a:focus-visible { outline: none; }

/* --------------------------------------------------------------------------
   Values list (Why Havilah Cottage) — editorial, deliberately NOT identical cards
   -------------------------------------------------------------------------- */

.values {
  display: grid;
  gap: var(--s-6);
}

.values li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-4);
  align-items: start;
  max-width: none;
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-purple-dark-a12);
}

/* Medallion: a purple disc inside a gold-gradient ring, the glyph in light gold
   (9.10:1) — the logo's purple hand and gold hearts. The ring is two background
   layers because border-image would ignore the radius. */
.values__icon {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 2px solid transparent;
  border-radius: var(--r-pill);
  background: linear-gradient(var(--c-purple-dark), var(--c-purple-dark)) padding-box,
              var(--g-gold) border-box;
  color: var(--c-gold-light);
}

.values__icon svg { width: 1.35rem; height: 1.35rem; }

/* The heading level follows the surrounding outline: h3 under the section's
   h2 on the homepage and in the style guide. h4 stays covered for a page that
   nests the values deeper. The size is pinned so the level never changes how
   they look. */
.values h3,
.values h4 {
  margin-bottom: var(--s-2);
  font-size: var(--fs-h3);
}

.values p { color: var(--c-muted); }

@media (min-width: 64em) {
  .values { grid-template-columns: 1fr 1fr; gap: var(--s-6) var(--s-8); }
}

/* --------------------------------------------------------------------------
   Statements — labelled short statements (Our Mission, Core Values)
   A description list, because each item is genuinely a term and its definition.
   Open editorial content on the section's own surface (decision P23): no
   banner, border, radius, shadow or panel, and no rule or frame in their
   place. The labels and the space around them do the grouping, so the ivory
   shows through everywhere.
   -------------------------------------------------------------------------- */

/* overflow-wrap lets a long word break instead of pushing past the column at
   large text sizes (a 200% browser font setting on a phone). */
.statements {
  display: grid;
  gap: var(--s-5);
  margin-top: var(--s-6);
  overflow-wrap: anywhere;
}

.statements__item {
  display: grid;
  gap: var(--s-2);
}

/* The brand document's lockup set as type, not as a banner: Playfair capitals
   in purple-dark (12.1:1 on ivory) with the second word in gold-dark
   (.statements__accent, 5.32:1). Never gold-light here: 1.42:1 on ivory. */
.statements dt {
  color: var(--c-purple-dark);
  font-family: var(--ff-head);
  font-size: var(--fs-h4);
  font-weight: var(--fw-head);
  line-height: var(--lh-head);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.statements__accent { color: var(--c-gold-dark); }

.statements dd { margin: 0; }

.statements__statement {
  font-style: italic;
  text-wrap: balance;
}

/* minmax(0, 1fr), not an auto column: an auto column would take the width of
   the longest capitalised value name and push past the text column. */
.statements__values {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* One small gold-dark dot per value, centred on the first line of its name.
   A pseudo-element, so the markup stays the name over its description. */
.statements__values li {
  position: relative;
  padding-left: var(--s-5);
}

.statements__values li::before {
  content: "";
  position: absolute;
  left: 0;
  top: calc(var(--fs-base) * var(--lh-head) / 2 - .25rem);
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background: var(--c-gold-dark);
}

.statements__values strong {
  display: block;
  color: var(--c-purple-dark);
  font-family: var(--ff-head);
  font-size: var(--fs-base);
  font-weight: var(--fw-head);
  line-height: var(--lh-head);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.statements__values p {
  margin: 0;
  color: var(--c-muted);
}

/* --------------------------------------------------------------------------
   Care journey — numbered because it is a real sequence
   -------------------------------------------------------------------------- */

.journey {
  display: grid;
  gap: var(--s-6);
  counter-reset: step;
}

.journey li {
  position: relative;
  max-width: none;
  padding-left: calc(3.25rem + var(--s-4));
  counter-increment: step;
}

.journey li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute;
  top: 0;
  left: 0;
  display: grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;
  /* The values' medallion: purple disc, gold-gradient ring. Border-box sizing
     keeps the circle at 3.25rem. */
  border: 2px solid transparent;
  background: linear-gradient(var(--c-purple-dark), var(--c-purple-dark)) padding-box,
              var(--g-gold) border-box;
  color: var(--c-gold-light);
  font-family: var(--ff-head);
  font-size: var(--fs-h4);
  border-radius: var(--r-pill);
}

/* Vertical gold connector on mobile. */
.journey li:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 3.25rem;
  left: 1.625rem;
  width: 1px;
  height: calc(100% + var(--s-6) - 3.25rem);
  background: var(--c-gold-dark-a40);
}

.journey h3 { margin-bottom: var(--s-2); }
.journey p { color: var(--c-muted); }

@media (min-width: 64em) {
  .journey li { padding-left: calc(3.25rem + var(--s-5)); }
}

/* --------------------------------------------------------------------------
   Service detail row — alternating image/copy (decision P3)
   -------------------------------------------------------------------------- */

.service-row + .service-row { margin-top: var(--s-9); }

/* These rows carry their own proportions rather than the shared .split--5-7,
   which other sections still rely on. The media column is 46% with a --s-6
   gap, so the photo lands ~14% wider than the shared split and sits closer to
   its copy. Below 64em .split's single column and --s-7 gap still apply. */
@media (min-width: 64em) {
  .service-row {
    grid-template-columns: 46fr 54fr;
    gap: var(--s-6);
  }

  .service-row--media-right { grid-template-columns: 54fr 46fr; }
  .service-row--media-right > :first-child { order: 2; }
  .service-row--media-right > :last-child { order: 1; }
}

.service-row__media img {
  width: 100%;
  border-radius: var(--r-md);
}

.service-row__media--pending {
  display: grid;
  place-items: center;
  aspect-ratio: 3 / 2;
  padding: var(--s-6);
  background: var(--c-lavender);
  border: 1px dashed var(--c-purple-dark-a20);
  border-radius: var(--r-md);
  color: var(--c-muted);
  text-align: center;
}

.service-row__body h3 { margin-bottom: var(--s-4); }

.includes {
  display: grid;
  gap: var(--s-3);
  margin-top: var(--s-5);
}

.includes li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-3);
  align-items: start;
  max-width: none;
}

.includes svg {
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: .3em;
  color: var(--c-gold-dark);
}

.includes__title {
  margin-bottom: var(--s-3);
  font-weight: var(--fw-bold);
}

/* --------------------------------------------------------------------------
   Comparison table — "common challenges" (decision P3)
   A real <table> above 64em; stacked labelled cards below.
   -------------------------------------------------------------------------- */

.compare {
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--c-white);
  box-shadow: var(--shadow-lift);
}

.compare caption {
  padding: var(--s-4);
  color: var(--c-muted);
  font-size: var(--fs-sm);
  text-align: left;
}

.compare th,
.compare td {
  padding: var(--s-4) var(--s-5);
  text-align: left;
  vertical-align: top;
}

.compare thead th {
  background: var(--c-purple-dark);
  color: var(--c-ivory);
  font-family: var(--ff-body);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: .02em;
}

/* Each challenge label is one phrase and stays on one line. nowrap also raises
   the column's min-content width, so the auto table layout gives it the room it
   needs instead of breaking "Household Tasks" across two lines. */
.compare tbody th {
  color: var(--c-purple-dark);
  font-family: var(--ff-head);
  font-size: var(--fs-h4);
  font-weight: var(--fw-head);
  white-space: nowrap;
}

.compare tbody td { color: var(--c-charcoal); }

.compare tbody tr + tr th,
.compare tbody tr + tr td { border-top: 1px solid var(--c-purple-dark-a12); }

/* Stacked layout below 64em. */
@media (max-width: 63.999em) {
  .compare,
  .compare tbody,
  .compare tr,
  .compare th,
  .compare td { display: block; }

  /* A table-caption inside a block parent gets wrapped in an anonymous table
     box and shrink-wraps to a narrow column. Make it a plain block. */
  .compare caption { display: block; padding-inline: 0; }

  .compare thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .compare { background: none; box-shadow: none; }

  .compare tbody tr {
    margin-bottom: var(--s-5);
    padding: var(--s-5);
    background: var(--c-white);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-lift);
  }

  .compare tbody tr + tr th,
  .compare tbody tr + tr td { border-top: 0; }

  .compare tbody th { padding: 0 0 var(--s-4); white-space: normal; }

  .compare tbody td { padding: var(--s-4) 0 0; border-top: 1px solid var(--c-purple-dark-a12); }

  /* The column name travels with the cell when the header row is hidden. */
  .compare tbody td::before {
    content: attr(data-label);
    display: block;
    margin-bottom: var(--s-1);
    color: var(--c-muted);
    font-size: var(--fs-sm);
    font-weight: var(--fw-bold);
    letter-spacing: .02em;
  }
}

/* --------------------------------------------------------------------------
   Team grid — rectangular portraits with white name-and-role panels
   -------------------------------------------------------------------------- */

.team-grid {
  display: grid;
  gap: var(--s-5);
}

.team-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--c-white);
  border-radius: 0 0 var(--r-md) var(--r-md);
  text-align: center;
}

/* Portrait rather than square: the cards sit in a wider container, so a 4:5
   frame gives the photo noticeably more height without making the row tall. */
.team-card__portrait {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 5;
  background: var(--c-lavender);
}

/* Same trap as the hero: without this the img's 100% height resolves against
   an auto-height <picture>, and only exact 4:5 photos happen to fill the frame. */
.team-card__portrait picture { width: 100%; height: 100%; }

.team-card__portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.team-card__caption {
  flex: 1;
  padding: var(--s-4) var(--s-3) var(--s-5);
}

.team-card__name {
  margin-bottom: var(--s-1);
  color: var(--c-gold-dark);
  font-family: var(--ff-head);
  font-size: var(--fs-h3);
}

.team-card__role {
  display: block;
  color: var(--c-charcoal);
  font-size: var(--fs-base);
}

.team-card__portrait--pending {
  padding: var(--s-5);
  color: var(--c-muted);
  font-size: var(--fs-sm);
  text-align: center;
}

@media (min-width: 40em) {
  .team-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 64em) {
  .team-grid { grid-template-columns: repeat(4, 1fr); }
}

/* --------------------------------------------------------------------------
   FAQ — native <details>, works with JS off
   -------------------------------------------------------------------------- */

.faq {
  border-bottom: 1px solid var(--c-purple-dark-a12);
}

.faq:first-of-type { border-top: 1px solid var(--c-purple-dark-a12); }

.faq > summary {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--s-4);
  align-items: center;
  padding: var(--s-5) var(--s-2);
  color: var(--c-purple-dark);
  font-family: var(--ff-head);
  font-size: var(--fs-h4);
  font-weight: var(--fw-head);
  cursor: pointer;
  list-style: none;
}

.faq > summary::-webkit-details-marker { display: none; }

.faq > summary:hover { color: var(--c-purple-medium); }

/* Custom plus/minus marker. */
.faq > summary::after {
  content: "";
  width: 1.5rem;
  height: 1.5rem;
  background:
    linear-gradient(var(--c-gold-dark) 0 0) center / 100% 2px no-repeat,
    linear-gradient(var(--c-gold-dark) 0 0) center / 2px 100% no-repeat;
  transition: transform var(--dur-fast) var(--ease-out);
}

.faq[open] > summary::after {
  background: linear-gradient(var(--c-gold-dark) 0 0) center / 100% 2px no-repeat;
  transform: rotate(180deg);
}

.faq__body {
  padding: 0 var(--s-2) var(--s-6);
}

.faq__body p { color: var(--c-muted); }

/* --------------------------------------------------------------------------
   CTA band
   -------------------------------------------------------------------------- */

.cta-band {
  background: var(--g-purple-deep);
  color: var(--c-ivory);
  text-align: center;
}

.cta-band h2 { color: var(--c-ivory); }

.cta-band p {
  margin: var(--s-4) auto 0;
  max-width: 44rem;
  color: var(--c-ivory-a85);
}

/* The roofline: the logo's two gables drawn in the gold gradient, standing in
   for a plain rule. Still an <hr>, so the thematic break keeps its meaning. */
.cta-band__rule {
  width: 4.5rem;
  height: 1.25rem;
  margin: 0 auto var(--s-5);
  border: 0;
  background: var(--g-gold);
  -webkit-mask: var(--shape-roofline) center / contain no-repeat;
          mask: var(--shape-roofline) center / contain no-repeat;
}

/* --------------------------------------------------------------------------
   Testimonials (SKILL.md §3, decisions P19 and P24)
   One homepage slot, two states. Until three testimonials have recorded
   consent and administration approval (content/testimonials.md), the slot
   shows the honest temporary state; then the carousel replaces it without a
   redesign. Never a quote, name, rating or card that is not genuine (rule 5).
   -------------------------------------------------------------------------- */

/* Pinned by class, so a demo heading at another level looks the same. */
.testimonials__title {
  font-size: var(--fs-h2);
  letter-spacing: var(--tracking-head);
}

/* The short gold accent rule under the heading. */
.testimonials__title::after {
  content: "";
  display: block;
  width: var(--s-8);
  height: 2px;
  margin-top: var(--s-4);
  background: var(--g-gold);
}

.testimonials__title--center::after { margin-inline: auto; }

/* --- Temporary state: the cottage doorway, waiting for its stories -------- */

/* The padding clears the arch at every width: the top padding is at least half
   the rise, so the first line always has 86.6% of the width, and the inline
   padding covers the rest (SKILL.md §8.1 has the geometry check). */
.testimonials__temporary {
  position: relative;
  max-width: 36rem;
  margin-inline: auto;
  padding: max(4.5rem, calc(var(--r-door-rise) * .5)) clamp(var(--s-5), 7%, var(--s-7)) var(--s-7);
  text-align: center;
}

/* A faint gold doorway: an arched outline, open at the foot, fading toward the
   floor. An outline only; the filled cottage door stays unique to Request Care. */
.testimonials__temporary::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid var(--c-gold-dark);
  border-bottom: 0;
  border-radius: 50% 50% 0 0 / var(--r-door-rise) var(--r-door-rise) 0 0;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, var(--c-purple-dark) 55%, transparent);
          mask-image: linear-gradient(to bottom, var(--c-purple-dark) 55%, transparent);
}

/* Balanced, because a centred two-line sentence reads badly with a short
   second line. */
.testimonials__temporary p {
  margin: var(--s-5) auto 0;
  color: var(--c-purple-dark);
  text-wrap: balance;
}

/* --- Active state: editorial head with the carousel controls ------------- */

.testimonials__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-5) var(--s-7);
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: var(--s-6);
}

/* overflow-wrap: anywhere also lowers the flex item's minimum width, so at a
   very large text size on a phone a long heading word breaks instead of
   pushing the whole head past the screen. */
.testimonials__intro {
  flex: 1 1 24rem;
  max-width: 40rem;
  overflow-wrap: anywhere;
}

.testimonials__intro p {
  margin-top: var(--s-5);
  color: var(--c-muted);
  text-wrap: balance;
}

/* --------------------------------------------------------------------------
   Carousel (testimonials): looping, with dots and accessible autoplay (P24)
   The carousel layout is the default; no-js.css turns it back into a grid and
   hides every control. testimonials.js moves the track with a transform, loops
   it with the fewest clones, builds the dots, and runs autoplay behind a
   visible Pause/Play that pauses on hover, keyboard focus, a press or drag, a
   hidden tab and when the cards are mostly off-screen.
   -------------------------------------------------------------------------- */

/* The rotation control, then Previous, then Next: the rotation control is the
   first thing a keyboard or screen reader meets. */
.carousel__controls {
  display: flex;
  flex: 1 1 100%;
  gap: var(--s-3);
  align-items: center;
  justify-content: flex-end;
}

/* testimonials.js hides the controls, and the dots, when every card already
   fits: there is nothing to move. */
.carousel__controls[hidden] { display: none; }

.carousel__button {
  display: grid;
  flex: none;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 0;
  background: var(--c-white);
  /* 50% purple gives the button boundary about 3:1 against the band. */
  border: 1px solid var(--c-purple-dark-a50);
  border-radius: var(--r-pill);
  color: var(--c-purple-dark);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}

/* The sprite has no intrinsic size; base.css only caps it at 100%. The shared
   down-chevron turns to point back or forward. */
.carousel__button svg { width: 1.25rem; height: 1.25rem; }
.carousel__button--prev svg { transform: rotate(90deg); }
.carousel__button--next svg { transform: rotate(-90deg); }

/* Set a little apart from the Previous/Next pair: it changes whether the cards
   move on their own, not which card shows. */
.carousel__button--rotation { margin-right: var(--s-2); }

.carousel__button:hover {
  background: var(--c-purple-dark);
  border-color: var(--c-purple-dark);
  color: var(--c-ivory);
}

.carousel__button:active { transform: translateY(1px); }

@media (min-width: 64em) {
  .carousel__controls { flex: 0 0 auto; }
}

/* The slides carry the gutter, so the viewport is pulled out by the same
   amount: card edges align with the content column and the shadows have room.
   clip, not hidden, so the viewport is never a scroll container and focusing a
   link inside a card can never scroll it out of step with the transform;
   hidden comes first as the fallback. pan-y pinch-zoom leaves vertical page
   scrolling and zoom to the browser while the script follows horizontal
   swipes. */
.carousel__viewport {
  margin: calc(var(--s-3) * -1) calc(var(--s-3) * -1) calc(var(--s-6) * -1);
  padding-block: var(--s-3) var(--s-6);
  overflow: hidden;
  overflow: clip;
  touch-action: pan-y pinch-zoom;
}

/* Set by testimonials.js only while a pointer drags the cards. */
.carousel__viewport.is-dragging {
  cursor: grabbing;
  user-select: none;
}

/* Registered so that following the pointer restyles only the track, not every
   card inside it. */
@property --drag {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

/* --index is the first card in view (testimonials.js sets it; the clones sit
   after the last card, one of them drawn just before the first), and --drag is
   the live pointer offset. Every card shares three subgrid rows (rating or
   mark, quote, attribution) at every width, so the cards always share one
   height and their names line up. */
.carousel__track {
  --per-view: 1;
  --index: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc(100% / var(--per-view));
  grid-template-rows: repeat(3, auto);
  transform: translateX(calc(var(--index, 0) * -100% / var(--per-view) + var(--drag, 0px)));
}

@media (min-width: 40em) {
  .carousel__track { --per-view: 2; }
}

@media (min-width: 64em) {
  .carousel__track { --per-view: 3; }
}

.carousel__slide {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  max-width: none;
  padding-inline: var(--s-3);
}

/* --------------------------------------------------------------------------
   Carousel dots: one per testimonial, below the cards (P24)
   testimonials.js fills the group; the row's height is reserved here, so that
   moves nothing. Each target is 44px tall and may shrink to 24px wide, so nine
   or twelve fit at 320px, around a small visible dot. The current one is a
   wider gold-dark pill: a change of shape, not of colour alone.
   -------------------------------------------------------------------------- */

.carousel__dots {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  min-height: 44px;
  margin-top: var(--s-5);
}

.carousel__dots[hidden] { display: none; }

/* The dots share the row equally, between 24 and 44px each. A 44px basis
   would wrap first and shrink second, splitting nine dots over two rows on a
   phone; a zero basis keeps them on one row down to 24px each (216px). */
.carousel__dot {
  display: grid;
  flex: 1 1 0;
  place-items: center;
  min-width: 24px;
  max-width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.carousel__dot::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: var(--r-pill);
  background: var(--c-purple-dark-a50);
  transition: width var(--dur) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}

.carousel__dot:hover::before { background: var(--c-purple-dark); }

/* After :hover, so the current dot keeps its gold under the pointer. */
.carousel__dot[aria-current="true"]::before {
  width: 24px;
  background: var(--c-gold-dark);
}

.carousel__dot:active::before { transform: scale(.85); }

/* The ring goes around the visible dot, not the tall invisible target. */
.carousel__dot:focus-visible { outline: none; }

.carousel__dot:focus-visible::before {
  outline: var(--focus-w) solid var(--focus-color);
  outline-offset: var(--focus-offset);
}

/* Windows high-contrast mode drops backgrounds, and every dot with them;
   system colours keep the row visible and the current dot distinct. */
@media (forced-colors: active) {
  .carousel__dot::before {
    forced-color-adjust: none;
    background: ButtonText;
  }

  .carousel__dot[aria-current="true"]::before { background: Highlight; }
}

/* --------------------------------------------------------------------------
   Testimonial card: an approved quote, its attribution, nothing invented
   -------------------------------------------------------------------------- */

/* Three subgrid rows (rating or mark, quote, attribution) shared with the
   other cards in the track; outside a track the rows are simply its own.
   overflow-wrap lets a long name or word at a large text size break instead of
   running past the card, which the viewport would clip. */
.testimonial {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid;
  padding: var(--s-6) var(--s-5) var(--s-5);
  background: var(--c-white);
  border: 1px solid var(--c-purple-dark-a12);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lift);
  overflow-wrap: anywhere;
}

/* The gold quotation mark in a small arched niche, like a cottage window: a
   full semicircle over a narrow box (the half-width radius), not --r-arch-sm,
   whose shallow rise reads as a generic icon chip at this size. It stands in
   for a rating whenever no genuine rating exists. The empty alternative text
   keeps it out of screen readers; older browsers fall back to the first
   declaration. */
.testimonial::before {
  content: "\201C";
  content: "\201C" / "";
  display: block;
  width: 2.75rem;
  height: 3.5rem;
  margin-bottom: var(--s-4);
  border-radius: 1.375rem 1.375rem var(--r-sm) var(--r-sm);
  background: var(--c-lavender);
  color: var(--c-gold-dark);
  font-family: var(--ff-head);
  font-size: 3.25rem;
  font-weight: var(--fw-head-strong);
  /* The mark sits high in its em box; this line height centres it in the niche. */
  line-height: 1.65;
  text-align: center;
}

/* A card whose reviewer's genuine 5 out of 5 is recorded shows the stars in
   place of the niche (content/testimonials.md rule 6). The modifier and the
   rating element always travel together, so the two never show at once. */
.testimonial--rated::before { content: none; }

/* Five solid gold-dark stars, 5.68:1 on the white card, read as one image-like
   label ("Rated 5 out of 5 stars"); the glyphs themselves are hidden. */
.testimonial__rating {
  margin-bottom: var(--s-4);
  color: var(--c-gold-dark);
  font-size: var(--fs-h4);
  line-height: 1;
  letter-spacing: .12em;
}

.testimonial__quote p { color: var(--c-charcoal); }

/* align-content keeps the name and relationship together when the shared
   attribution row is taller than this card needs. */
.testimonial__cite {
  display: grid;
  align-content: start;
  gap: var(--s-1);
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--c-purple-dark-a12);
}

.testimonial__name {
  color: var(--c-purple-dark);
  font-family: var(--ff-head);
  font-size: var(--fs-base);
  font-weight: var(--fw-head-strong);
  line-height: var(--lh-head);
}

.testimonial__meta {
  color: var(--c-muted);
  font-size: var(--fs-sm);
}

/* A standalone link, so it needs the 24px minimum in its own right. */
.testimonial__source {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  min-height: 24px;
  font-size: var(--fs-sm);
}

/* --------------------------------------------------------------------------
   Form field (SKILL.md §3) — labels always visible
   -------------------------------------------------------------------------- */

.field { display: grid; gap: var(--s-2); margin-bottom: var(--s-5); }

.field label {
  font-weight: var(--fw-bold);
  color: var(--c-purple-dark);
}

.field .req { color: var(--c-muted); font-weight: var(--fw-body); }

.field .hint {
  margin: 0;
  color: var(--c-muted);
  font-size: var(--fs-sm);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 48px;
  padding: var(--s-3) var(--s-4);
  background: var(--c-white);
  border: 1px solid var(--c-muted);
  border-radius: var(--r-sm);
}

.field textarea { min-height: 9rem; resize: vertical; }

.field input:hover,
.field select:hover,
.field textarea:hover { border-color: var(--c-purple-dark); }

.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"],
.field select[aria-invalid="true"] { border-color: var(--c-error); border-width: 2px; }

.field .error {
  display: flex;
  gap: var(--s-2);
  align-items: center;
  margin: 0;
  color: var(--c-error);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
}

.field .error svg { flex: none; width: 1.1em; height: 1.1em; }

fieldset { margin: 0 0 var(--s-5); padding: 0; border: 0; }

legend { padding: 0 0 var(--s-3); color: var(--c-purple-dark); font-weight: var(--fw-bold); }

.error-summary {
  margin-bottom: var(--s-6);
  padding: var(--s-5);
  background: var(--c-white);
  border: 2px solid var(--c-error);
  border-radius: var(--r-md);
}

.error-summary h2 { margin-bottom: var(--s-3); color: var(--c-error); font-size: var(--fs-h4); }

.error-summary ul { display: grid; gap: var(--s-2); }

.error-summary a { color: var(--c-error); font-weight: var(--fw-bold); }

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

/* --------------------------------------------------------------------------
/* --------------------------------------------------------------------------
   Pending block — copy awaiting administration's approval (CLAUDE.md rule 3)
   The structure of a page can be reviewed before its copy is approved, but an
   unapproved claim must never read as published. This block states plainly
   that it is not approved, so a reviewer can judge the layout without any
   risk of the wording being taken as live. It pairs with a verify marker in
   the source, which is what blocks launch.
   Wording inside it is a proposal only. It never ships to a public page.
   -------------------------------------------------------------------------- */

.pending {
  padding: var(--s-6);
  background: var(--c-lavender);
  border: 1px dashed var(--c-purple-dark-a20);
  border-radius: var(--r-md);
}

.pending__flag {
  display: block;
  margin-bottom: var(--s-3);
  color: var(--c-gold-dark);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: .06em;
}

.pending__title {
  margin-bottom: var(--s-3);
  font-size: var(--fs-h4);
}

.pending p { color: var(--c-muted); }

.pending p + p { margin-top: var(--s-3); }

/* --------------------------------------------------------------------------
   Page hero — inner pages (SKILL.md §3)
   The homepage hero is a different component: it is built around the
   background video and the trust strip, and lives in pages/home.css. This is
   the quieter inner-page header, a single photograph under the brand scrim.
   It carries no video, so the image is the LCP element and is never lazy.
   -------------------------------------------------------------------------- */

.page-hero {
  position: relative;
  display: grid;
  isolation: isolate;
  min-height: min(26rem, 62svh);
  background: var(--c-purple-dark);
  color: var(--c-ivory);
  overflow: hidden;
}

.page-hero__media {
  position: absolute;
  inset: 0;
  z-index: var(--z-hero-media);
}

/* Same trap as the homepage hero: <picture> is a block with auto height, so
   the img's 100% has nothing to resolve against and the photo stops at its
   natural ratio, leaving a flat band under it. */
.page-hero__media picture { height: 100%; }

.page-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 38%;
}

.page-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: var(--z-hero-scrim);
  background: var(--g-hero-scrim-v);
}

.page-hero__inner {
  position: relative;
  z-index: var(--z-hero-content);
  align-self: center;
  width: 100%;
  padding-block: var(--s-8);
}

.page-hero__copy { max-width: 36rem; }

.page-hero h1 {
  color: var(--c-ivory);
  font-weight: var(--fw-head-strong);
}

.page-hero__lede {
  margin-top: var(--s-5);
  max-width: 46ch;
  color: var(--c-ivory);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
}

.page-hero .btn-row { margin-top: var(--s-6); }

/* The trust strip sits on the hero's foot, as it does on the homepage. The
   reference layout puts provider claims here; ours carries the approved four.
   Focus rings inside the hero come from base.css's on-dark list: the default
   deep gold is 2.28:1 on this scrim, so .page-hero is listed there. */
.page-hero__trust {
  position: relative;
  z-index: var(--z-hero-content);
  align-self: end;
  background: var(--c-purple-dark-a85);
  border-top: 1px solid var(--c-gold-light-a40);
  color: var(--c-ivory);
}

/* Responsive overrides come after the rules they override: every selector here
   is a single class, so the later rule wins (CLAUDE.md §7). */
@media (min-width: 64em) {
  .page-hero { min-height: min(30rem, 64svh); }

  /* The subject sits centre-right; bias the crop so the copy side stays calm. */
  .page-hero__media img { object-position: 70% 50%; }

  /* The brand's left-to-right gradient, as on the homepage hero. */
  .page-hero__scrim { background: var(--g-hero-scrim-h); }

  .page-hero__inner { padding-block: var(--s-9); }
}

/* --------------------------------------------------------------------------
   Breadcrumb — inner pages only
   -------------------------------------------------------------------------- */

.breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  font-size: var(--fs-sm);
}

.breadcrumb li { max-width: none; }

.breadcrumb li + li::before { content: "/"; margin-right: var(--s-2); color: var(--c-muted); }

/* A standalone link, so it needs the 24px minimum in its own right. */
.breadcrumb a { display: inline-flex; align-items: center; min-height: 24px; }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

/* A 2px gold gleam along the top edge separates the footer from the CTA band
   and hides the seam where the band's lighter right end meets solid purple. */
.site-footer {
  background: var(--g-gold) center top / 100% 2px no-repeat, var(--c-purple-dark);
  color: var(--c-ivory-a85);
  padding-block: var(--s-8) var(--s-6);
}

.site-footer a { color: var(--c-ivory); text-decoration: none; }
.site-footer a:hover { color: var(--c-gold-light); text-decoration: underline; }

.site-footer h2,
.site-footer h3 { color: var(--c-ivory); }

.footer__grid {
  display: grid;
  gap: var(--s-7);
}

.footer__brand-name {
  font-family: var(--ff-head);
  font-size: var(--fs-h3);
  font-weight: var(--fw-head);
  color: var(--c-ivory);
  line-height: 1.2;
}

.footer__tagline {
  margin-top: var(--s-3);
  color: var(--c-gold-light);
  font-style: italic;
}

/* Sentence case in light gold (9.10:1) — no tracked-out all-caps labels. */
.footer__col h3 {
  margin-bottom: var(--s-4);
  color: var(--c-gold-light);
  font-family: var(--ff-body);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: .01em;
}

.footer__col ul { display: grid; gap: var(--s-1); }

.footer__col li { max-width: none; font-size: var(--fs-sm); }

/* Text links are 17px tall on their own — short of the 24×24 minimum in
   WCAG 2.2 SC 2.5.8. The gap shrinks by as much as the link grows, so the
   rhythm is unchanged. */
.footer__col li a,
.footer__legal a {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
}

.footer__phone {
  display: inline-flex;
  gap: var(--s-2);
  align-items: center;
  font-family: var(--ff-head);
  font-size: var(--fs-h4);
}

.footer__phone svg { width: 1em; height: 1em; color: var(--c-gold-light); }

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-5);
  align-items: center;
  justify-content: space-between;
  margin-top: var(--s-8);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-gold-light-a40);
  font-size: var(--fs-sm);
}

.footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-5);
}

.footer__legal li { max-width: none; }

@media (min-width: 40em) {
  .footer__grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 64em) {
  .footer__grid { grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: var(--s-8); }
}
