/* Fonts ------------------------------------------------------------------- */

/* Fraunces (headings) and Karla (body), per the design brief. Both SIL Open
   Font License 1.1 — see assets/fonts/OFL-Fraunces.txt and OFL-Karla.txt.

   Self-hosted rather than pulled from Google's CDN, matching how Leaflet is
   vendored: the version is pinned, and it keeps working if the CDN is
   blocked. It also means no visitor IP reaches a third party, which matters
   more than usual for a site used by people seeking asylum.

   Two Latin subsets per family, each with an explicit `unicode-range`, so the
   browser fetches only the ones a given page actually needs.

   It used to be latin alone. That was correct for the original three
   languages — Albanian's ë/ç and German's ä/ö/ü/ß all sit inside Latin-1 — but
   the nine languages of Content Expansion Blueprint Section 2 brought in
   Turkish and Kurmanji Kurdish, and their ğ/Ğ/ş/Ş/İ are Latin Extended-A,
   outside it. Without latin-ext a page translated into Turkish renders those
   five characters from a system fallback MID-WORD, so "değil" arrives in two
   different typefaces. Hence the second face per family.

   The ranges are Google's own, and they are what keeps this cheap: an English
   visitor never downloads a latin-ext file, because nothing on the page is in
   its range. Only a visitor who has switched to Turkish or Kurmanji pays for
   it, which is exactly who needs it.

   The non-Latin scripts — Arabic, Persian, Pashto, Sorani, Amharic, Tigrinya —
   have no coverage here by design and fall through to the system font for
   their script, as before. `swap` so text paints immediately on a slow
   connection. */
@font-face {
  font-family: "Fraunces";
  src: url("/assets/fonts/fraunces-latin-var.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Fraunces";
  src: url("/assets/fonts/fraunces-latin-ext-var.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

@font-face {
  font-family: "Karla";
  src: url("/assets/fonts/karla-latin-var.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Karla";
  src: url("/assets/fonts/karla-latin-ext-var.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

/* Lexend (service-user-facing pages only — Clothes and the Get Help section,
   per Content Expansion Blueprint Section 1). Designed for reading
   proficiency: wide apertures, generous spacing, unambiguous letterforms —
   the qualities that matter most for someone reading English as a second or
   third language. SIL OFL 1.1, see assets/fonts/OFL-Lexend.txt.

   Self-hosted and latin-subset for the same reasons as Fraunces and Karla
   above; 39KB, and it REPLACES both of them on the pages that opt in rather
   than adding to them, so those pages carry less font weight, not more.

   Its x-height is 0.525em against Karla's 0.478 — the same nominal size reads
   about a tenth larger. That is the point of the face, but it means a line
   set in Lexend occupies more width than the same line in Karla, so check
   headings on narrow viewports when a service-user page is built. */
@font-face {
  font-family: "Lexend";
  src: url("/assets/fonts/lexend-latin-var.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Lexend";
  src: url("/assets/fonts/lexend-latin-ext-var.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

/* Tokens ------------------------------------------------------------------ */

/* Palette per the design brief (6 Aug 2026): a warm-leaning mid blue carries
   navigation, headings and structure; gold is an accent only — CTAs, icon
   details, hover and active states — never a background wash. The base is a
   warm off-white rather than stark white, and body text a dark blue-grey
   rather than pure black, so the warmth carries through long-form copy. */
:root {
  --color-primary: #2f5d8a;
  --color-primary-deep: #1e3f61;
  --color-primary-soft: #e8eef5;

  --color-gold: #c98a1f;
  /* Pale wash for callout panels. Light enough that body text keeps its full
     contrast on top, so gold can carry emphasis without becoming a fill. */
  --color-gold-soft: #fdf4e3;
  /* Gold is too light to carry white text or to sit on the base as body copy;
     this darker step is the one to use when gold has to be legible text. */
  --color-gold-deep: #8a5c0d;
  /* The mirror of --color-gold-deep, for gold sitting ON the blue rather than
     on the base. --color-gold measures 2.3:1 against --color-primary and so
     cannot carry an icon detail there; this lifted step reaches 3.7:1.
     Deliberately NOT re-pointed by contrast mode — that block darkens gold to
     hold its own against white, which is the opposite of what a light-on-dark
     panel needs. Against the darker contrast-mode blue this only improves. */
  --color-gold-on-dark: #e8b64d;

  /* Donation tiers (Content Expansion Blueprint Step 8). The only place the
     site uses colour semantically rather than for brand, so they sit apart
     from the palette above: green/amber/red is a convention a donor already
     knows, and reading it takes no English at all — which is why it earns the
     exception. Nothing depends on the colour alone; the tick, question mark
     and cross carry the same meaning with the hue removed.

     Amber is --color-gold-deep rather than a new hue, so "check first" lands
     on the same tone the site already uses for "pay attention to this".
     Each measures at least 5:1 against both the page base and the tier panel,
     so they stay legible as text, not only as marks. */
  --color-tier-yes: #17703a;
  --color-tier-maybe: var(--color-gold-deep);
  --color-tier-no: #b3261e;

  --color-text: #232f3a;
  --color-muted: #55606b;
  --color-bg: #fbf9f4;
  --color-surface: #f2eee6;
  --color-line: #ddd6ca;
  /* --color-line is a decorative divider at 1.37:1 against the base, which is
     fine for card edges but too faint to mark the boundary of a control.
     Anything a visitor has to find and operate uses this instead (3.7:1,
     clearing the 3:1 floor for UI component boundaries). */
  --color-line-strong: #8a8073;
  /* Between the two: visible enough to read as a frame around content that
     sits on its own ground (the sponsor tiles), without the weight of a
     control boundary. */
  --color-line-frame: #c4baa6;
  --color-accent-text: #ffffff;

  /* The scaffold's original names, remapped onto the palette above so the
     rules already written against them keep resolving without a sweep.
     `--color-warm` was terracotta and meant "supporter-facing accent"; gold
     now fills that role. */
  --color-accent: var(--color-primary);
  --color-accent-deep: var(--color-primary-deep);
  --color-warm: var(--color-gold);

  --font-display: "Fraunces", "Iowan Old Style", Charter, Georgia,
    "Noto Serif", serif;
  --font-body: "Karla", system-ui, -apple-system, "Segoe UI", Helvetica, Arial,
    sans-serif;

  --step-0: 1rem;
  --step-1: 1.25rem;
  --step-2: 1.75rem;
  --step-3: 2.5rem;
  --step-display: clamp(2.1rem, 1.2rem + 3.4vw, 3.5rem);
  /* The drop-in hours. This used to be the largest type on the homepage
     (2.4–4rem); Oscar asked for it smaller, so it now matches the size the
     same line already had in the support dialog, and the card's "Get help"
     button carries the emphasis instead. */
  --step-hours: clamp(1.9rem, 1.2rem + 2.4vw, 2.5rem);

  --space: 1rem;
  --wrap: 68rem;
  --radius: 6px;
}

/* Mobile type scale ------------------------------------------------------- */

/* Below 40rem only, and every curve here is built to arrive at its desktop
   value EXACTLY at 640px — 28px, 40px, 40.96px and 52.16px respectively — so
   the two sides meet with no step and nothing above the breakpoint moves.

   Two of these were overflows rather than preferences.

   --step-3 was a flat 2.5rem at every width. "Communications" is a single
   unbreakable word 8.18em wide, so at 40px it is 327px of text in the 328px
   column a 360px phone leaves — before the width the title icon takes off
   the line in `h1.h-icon`. It ran off the page.

   --step-2 follows it down because it has to, not because it was too big:
   leave it at 1.75rem and a 28px h2 sits level with a 29px h1.

   --step-display was brought down alongside the old, larger --step-hours, so
   the hours would still out-rank the strapline on a phone.

   --step-1 closes the scale. It is the one here that is a preference rather
   than a fix: a flat 1.25rem left h3 only 3px under a 23px h2, and it is also
   the size behind the lede, the drop-in card's three supporting lines, the
   reassurance checklist and the tenets — which is most of what reads as
   oversized on a phone. At 18.4px against a 16px body it still sits clearly
   above running text. The resulting mobile scale is 16 / 18.4 / 23 / 30, a
   consistent step of about 1.25 the whole way up. */
@media (max-width: 40rem) {
  :root {
    --step-1: clamp(1.1rem, 0.99rem + 0.65vw, 1.25rem);
    --step-2: clamp(1.45rem, 0.95rem + 2vw, 1.75rem);
    --step-3: clamp(1.65rem, 0.94rem + 3.9vw, 2.5rem);
    --step-display: clamp(1.6rem, 0.16rem + 6vw, 3.5rem);

    /* The hours are `white-space: nowrap` by design — "10:30am-1:30pm" is the
       one string on this site that must not break mid-range — and at that size
       they simply did not fit. The old curve only cleared the drop-in card
       from a 433px viewport upward, so it overflowed on every phone held in
       portrait: 26px past the panel edge at 390, 45px at 360. It looked merely
       tight in screenshots only because those were taken at ~430px, right on
       the boundary where it stops fitting.

       So the size is capped by what that string can actually occupy rather
       than by a chosen curve. 5rem is the padding around it — 1rem a side from
       .wrap plus 1.5rem a side from .dropin — and 9.2 is the string's width as
       a multiple of its own font size, measured out of the font files: 8.2em
       in Fraunces, 9.06em in the readable-font stack once its letter-spacing
       is counted. Sized for the wider of the two, so turning on the readable
       font cannot bring the overflow back. Both terms are in rem, so this
       stays correct when the accessibility toolbar scales the root size and
       the padding grows with it.

       min(), not a replacement clamp: on all but the narrowest phones the
       curve is already the smaller of the two and takes over untouched. */
    --step-hours: min(
      clamp(1.9rem, 1.2rem + 2.4vw, 2.5rem),
      calc((100vw - 5rem) / 9.2)
    );
  }

  /* Backstop. Every title on the site now fits with room to spare, but a
     longer one added later should wrap rather than run off the page. */
  h1,
  h2 {
    overflow-wrap: break-word;
  }
}

/* Service-user page scope ------------------------------------------------- */

/* Opt in per page with `serviceUser: true` in front matter, which puts
   `page-service` on <html> in base.njk — the same opt-in shape as `map: true`.

   Re-points the two font tokens rather than overriding components, so it
   reaches everything built against them, including anything added later. Both
   tokens, not just the body one: on these pages comprehension outranks the
   brand serif, and a Fraunces heading over Lexend copy would keep the display
   face exactly where a struggling reader meets the page first.

   MUST stay above the `html.a11y-readable` block below. Both selectors are
   one class on <html>, so they carry identical specificity and source order
   decides — a visitor who has asked for the readable font has to win over a
   page-level default, not lose to it. Do not move this block downward. */
html.page-service {
  --font-display: "Lexend", system-ui, -apple-system, "Segoe UI", Helvetica,
    Arial, sans-serif;
  --font-body: "Lexend", system-ui, -apple-system, "Segoe UI", Helvetica,
    Arial, sans-serif;
}

/* Accessibility toolbar states ------------------------------------------- */

/* Every size token is in rem, so moving the root font size scales type and
   spacing together rather than just growing text out of its containers. */
html.a11y-text-lg { font-size: 112.5%; }
html.a11y-text-xl { font-size: 125%; }

/* Contrast mode re-points the tokens instead of overriding components, so it
   reaches anything built against them — including anything added later. */
html.a11y-contrast {
  --color-primary: #10365c;
  --color-primary-deep: #0a2440;
  --color-primary-soft: #ffffff;
  --color-gold: #7a4f08;
  --color-gold-deep: #6b4407;
  --color-text: #000000;
  --color-muted: #1c2630;
  --color-bg: #ffffff;
  --color-surface: #f2f2f2;
  --color-line: #4a5560;
  --color-line-strong: #1c2630;
  --color-line-frame: #4a5560;
  --color-gold-soft: #ffffff;
  /* The tier hues darkened against the white ground contrast mode paints. */
  --color-tier-yes: #0d5c2e;
  --color-tier-no: #8f1d15;
}

html.a11y-contrast a {
  text-decoration: underline;
}

/* Contrast mode darkens gold to hold its own contrast against white, which
   flips which text colour can sit on it — black would drop to 2.9:1. */
html.a11y-contrast .button--warm {
  color: var(--color-accent-text);
}

/* Drops the serif and widens spacing. Atkinson Hyperlegible is designed for
   low vision and ships with some systems; the rest of the stack is chosen for
   wide, open letterforms rather than character. */
html.a11y-readable {
  --font-display: "Atkinson Hyperlegible", Verdana, "DejaVu Sans", Tahoma,
    sans-serif;
  --font-body: "Atkinson Hyperlegible", Verdana, "DejaVu Sans", Tahoma,
    sans-serif;
}

html.a11y-readable body {
  line-height: 1.8;
  letter-spacing: 0.01em;
  word-spacing: 0.05em;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--color-text);
  background: var(--color-bg);
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.2;
  margin: 0 0 0.5em;
}

h1 { font-size: var(--step-3); }
h2 { font-size: var(--step-2); }
h3 { font-size: var(--step-1); }
h4 { font-size: var(--step-0); }

p { margin: 0 0 1em; }

a {
  color: var(--color-accent);
}

/* An email address is one unbreakable token, and the longer ones
   (volunteers@stchadssanctuary.co.uk) are wider than a 360px phone at the
   toolbar's largest text step. `anywhere` only breaks when the address could
   not otherwise fit, so at normal sizes nothing changes. */
a[href^="mailto:"] {
  overflow-wrap: anywhere;
}

img {
  max-width: 100%;
  height: auto;
}

code {
  background: var(--color-surface);
  padding: 0.1em 0.35em;
  border-radius: 3px;
  font-size: 0.9em;
}

:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
}

/* Layout ------------------------------------------------------------------ */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--space);
}

.section {
  padding-block: calc(var(--space) * 2.5);
}

.prose {
  max-width: 44rem;
}

/* Long single-column pages run as an undifferentiated stack otherwise. Extra
   air above each subheading — but not the first — groups each heading with
   the copy it introduces rather than floating between the two.

   The rule sits ABOVE the heading rather than under it. Underlining the text
   would put the web's strongest "this is a link" signal directly above the
   real inline links in this copy, and `html.a11y-contrast a` underlines every
   link — so in contrast mode underlined headings and links would be
   indistinguishable. A rule above says "new section" without touching the
   type, and clears Fraunces' descenders entirely. */
.prose h2 {
  margin-top: calc(var(--space) * 2.5);
  padding-top: calc(var(--space) * 1.25);
  border-top: 1px solid var(--color-line);
}

.prose > h1 + h2,
.prose > :first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* The callout is already a bounded panel with its own edge — a divider inside
   it would be separating the panel from itself. */
.prose .callout h2 {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.lede {
  font-size: var(--step-1);
  color: var(--color-muted);
}

/* Marks unwritten copy so it is obvious what still needs filling in. */
.placeholder {
  color: var(--color-muted);
  font-style: italic;
}

/* Removed from view but kept for assistive tech — the accessible name behind
   an icon-only control. Not `display: none`, which would hide it from screen
   readers too, which is the whole point of the class. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: -9999px;
}

.skip-link:focus {
  left: var(--space);
  top: var(--space);
  z-index: 10;
  padding: 0.5em 1em;
  background: var(--color-accent);
  color: var(--color-accent-text);
  border-radius: var(--radius);
}

/* Utility bar ------------------------------------------------------------- */

/* Holds the accessibility toolbar and the translate widget in one strip. */
.utility-bar {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-line);
  font-size: 0.9rem;
}

.utility-bar__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem var(--space);
  padding-block: 0.35rem;
}

/* The translate widget partial is owned by the translate work and left
   untouched, so its standalone framing — full-width band, its own centred
   .wrap — is unwound here rather than there. */
.utility-bar .translate-bar {
  background: none;
  border-bottom: 0;
}

.utility-bar .translate-bar .wrap {
  max-width: none;
  margin-inline: 0;
  padding-inline: 0;
}

.utility-bar .translate-bar__inner {
  padding-block: 0;
}

/* Accessibility toolbar --------------------------------------------------- */

.a11y-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.6rem;
}

.a11y-bar[hidden] {
  display: none;
}

.a11y-bar__label {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-muted);
}

.a11y-bar__controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.a11y-button {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.2rem 0.5rem;
  font-family: var(--font-body);
  font-size: 0.8rem;
  line-height: 1.4;
  color: var(--color-primary);
  background: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
}

.a11y-button:hover {
  border-color: var(--color-line-strong);
}

/* Gold marks the active state — an accent, not a fill. */
.a11y-button[aria-pressed="true"] {
  color: var(--color-gold-deep);
  border-color: var(--color-gold);
  background: var(--color-bg);
  font-weight: 600;
}

/* Small glyph carrying the control's meaning, alongside the text label
   rather than instead of it. */
.a11y-button__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.15rem;
  height: 1.15rem;
  font-family: var(--font-display);
  font-size: 0.8rem;
  line-height: 1;
  border: 1px solid currentColor;
  border-radius: 3px;
}

/* Half-filled square, reading as a contrast swatch. */
.a11y-button__mark--split {
  background: linear-gradient(
    to right,
    currentColor 0 50%,
    transparent 50% 100%
  );
}

/* 44px on the touch device, where these are 26px — two pixels over the 24px
   minimum, on the three controls aimed squarely at people who have most
   trouble hitting a small one. The type stays where it is; only the box grows,
   so the strip still reads as quiet utility rather than a row of buttons.

   It costs about 18px of height at the very top of every page, which is the
   wrong direction for a phone already carrying ~290px of chrome before the
   site starts. Collapsing this whole strip behind one control is the fix for
   that, and it is a change to make deliberately rather than as a side effect
   of sizing a target. */
@media (max-width: 40rem) {
  /* Height only. Widening these by even 0.1rem a side takes the three of them
     from 319px to 329px, which is wider than the 328px a 360px phone has —
     they drop to a second row and the strip costs another 50px. The height is
     what the target size needed; the width was never the problem. */
  .a11y-button {
    min-height: 2.75rem;
  }

  .translate-reset {
    min-height: 2.75rem;
  }

  /* Native control, so this is a floor rather than a layout — the select sizes
     itself around its own text and lands near 30px unaided. */
  #google_translate_element .goog-te-combo,
  .translate-fallback__select {
    min-height: 2.75rem;
  }
}

/* Translate bar ----------------------------------------------------------- */

.translate-bar {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-line);
  font-size: 0.9rem;
}

.translate-bar__inner {
  display: flex;
  /* Wraps since the switcher went from three languages to nine. A native
     select sizes itself to its WIDEST option, so the control grew from the
     width of "German" to the width of "Kurdî (Kurmancî)" — and at the
     accessibility toolbar's 125% text step that pushed "Show original" off
     the side of a 360px phone. The row now breaks instead of overflowing. */
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.6rem;
  padding-block: 0.4rem;
}

/* Replaces the "Show original" link from Google's suppressed banner. Styled
   as a quiet text control so it sits beside the dropdown without competing
   with the header below it. */
.translate-reset {
  padding: 0.15rem 0.4rem;
  font-family: var(--font-body);
  font-size: 0.8rem;
  line-height: 1.4;
  color: var(--color-accent);
  background: none;
  border: 0;
  border-radius: var(--radius);
  text-decoration: underline;
  cursor: pointer;
}

.translate-reset:hover {
  color: var(--color-accent-deep);
}

/* The rules above set `background`/`padding` but never `display`, so the UA's
   `[hidden] { display: none }` still applies — this is here so a later edge
   that does set `display` can't silently reveal the control. */
.translate-reset[hidden] {
  display: none;
}

/* Google Translate overrides ---------------------------------------------
   Suppress Google's injected top banner and restyle the gadget to Section 8's
   tokens, so the switcher reads as site UI rather than a bolted-on widget.

   Scoped deliberately: `.goog-te-gadget` itself carries the `skiptranslate`
   class, so a blanket `.skiptranslate { display: none }` would hide the
   dropdown and break the feature. The banner is a *body-level* wrapper, and
   the gadget is nested inside `#google_translate_element`, so the child
   combinator below separates them. The two iframe classes are the legacy and
   current (TE_20260804) banner names — Google's obfuscated names churn, so
   both are listed to survive a rename in either direction. */
body > .skiptranslate,
iframe.goog-te-banner-frame,
iframe.VIpgJd-ZVi9od-ORHb-OEVmcd {
  display: none !important;
}

/* Google sets `top: 40px` inline on <body> to make room for that banner. */
body {
  top: 0 !important;
}

/* Scoped through the #id deliberately. Google's own sheet is injected into
   <head> at runtime, i.e. *after* this file, and it ships
   `.goog-te-gadget .goog-te-combo { margin: 4px 0 }` — identical specificity
   to a bare `.goog-te-gadget .goog-te-combo`, so an unscoped rule here would
   lose the margin on cascade order alone. The id (1,1,0) beats anything in
   their sheet outright, and avoids sprinkling !important. */
#google_translate_element .goog-te-gadget {
  font-family: var(--font-body);
  font-size: 0.7rem;
  line-height: 1.4;
  color: var(--color-muted);
  /* Google's sheet sets `nowrap` on the gadget, which holds the select and
     "Powered by Translate" on one unbreakable line. On a 360px phone at the
     toolbar's largest text step that line is wider than the screen and the
     whole page scrolls sideways. Letting it wrap drops the credit under the
     select instead. */
  white-space: normal;
}

/* "Powered by Google Translate" — kept, but toned down to the muted token.
   Google's sheet renders it bold #444; attribution stays legible, just quiet. */
#google_translate_element .goog-te-gadget a,
#google_translate_element .goog-te-gadget a:link,
#google_translate_element .goog-te-gadget a:visited,
#google_translate_element .goog-te-gadget a:hover {
  color: var(--color-muted);
  font-weight: 400;
}

/* The gadget is a flex item, and a flex item refuses to shrink below its
   content's intrinsic width unless told to — so without `min-width: 0` here
   the select's own width wins and the max-width below never gets a chance. */
#google_translate_element {
  min-width: 0;
  max-width: 100%;
}

/* The backup select (translate-widget.njk) shares this styling, so if
   Google's widget fails the visitor sees the same control in the same place. */
#google_translate_element .goog-te-combo,
.translate-fallback__select {
  /* Hard ceiling: whatever the longest language name turns out to be in
     whichever system font renders its script, the control cannot be wider
     than the strip holding it. */
  max-width: 100%;
  margin: 0;
  padding: 0.15rem 0.4rem;
  font-family: var(--font-body);
  font-size: 0.9rem;
  line-height: 1.4;
  color: var(--color-text);
  background: var(--color-bg);
  /* A control boundary, not a divider — needs the stronger line. */
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius);
}

#google_translate_element .goog-te-combo:hover,
.translate-fallback__select:hover {
  border-color: var(--color-accent);
}

.translate-fallback {
  min-width: 0;
  max-width: 100%;
}

/* Same guard as .translate-reset[hidden]: nothing sets `display` on this yet,
   but a later rule that did would silently show the backup all the time. */
.translate-fallback[hidden] {
  display: none;
}

/* Belt and braces: the "G" sprite only ships with InlineLayout.SIMPLE, but
   this keeps the bar clean if the layout is ever switched back. */
#google_translate_element .goog-te-gadget img {
  display: none;
}

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

.site-header {
  border-bottom: 1px solid var(--color-line);
}

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

/* Logo and name as one lockup. The name is the part that has to be read, so
   it gets the display face at a size that holds its own against the CTAs on
   the same row; the logo is the part that has to be recognised, so it gets
   height. A hairline gold rule between them ties the two into a single mark
   rather than an image with a caption beside it. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--color-primary-deep);
}

.brand__text {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding-left: 0.6rem;
  border-left: 2px solid var(--color-gold);
}

/* Stacked over two lines deliberately: "St Chad's / Sanctuary" is a compact
   block that sits beside the logo at any width, where a single line would
   either crowd the CTAs on desktop or push the Menu button off a phone. */
.brand__name {
  display: flex;
  flex-direction: column;
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.01em;
}

.brand:hover .brand__name {
  color: var(--color-primary);
}

@media (min-width: 40em) {
  .brand {
    gap: 1.1rem;
  }

  .brand__text {
    padding-left: 1.1rem;
  }

  .brand__name {
    font-size: 2rem;
  }
}

/* The toolbar's two larger text steps on a phone. Every rem in the lockup
   grows with them, and before the name was added the header never lost the
   Menu button to a second row at any step — the lockup must not change that.
   So here it is held in px, a little under its default size: the text steps
   exist for reading copy, and the name at 18px is still legible, whereas
   Menu (which does keep growing) is the control a visitor at these steps
   most needs. Sized to keep one row down to a 360px phone. */
@media (max-width: 40em) {
  html.a11y-text-lg .brand__logo,
  html.a11y-text-xl .brand__logo {
    height: 46px;
  }

  html.a11y-text-lg .brand__name,
  html.a11y-text-xl .brand__name {
    font-size: 18px;
  }

  html.a11y-text-lg .brand,
  html.a11y-text-xl .brand {
    gap: 10px;
  }

  html.a11y-text-lg .brand__text,
  html.a11y-text-xl .brand__text {
    padding-left: 10px;
  }
}

/* Contrast mode underlines every link so none is identified by colour alone.
   The home lockup is the one exception: it is recognisable by position and
   form, and an underline through a two-line name reads as a rendering fault. */
html.a11y-contrast .brand {
  text-decoration: none;
}

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

/* Phone number and Donate, sharing the top row with the logo and Get Help.
   The nav then takes a row of its own — eight nav items plus the header's
   actions will not sit on one line at any realistic width, and the nav was
   already dropping to its own row below the mobile breakpoint, so this
   extends that arrangement upward rather than inventing a second layout.

   `margin-left: auto` keeps the cluster against the right edge if a large
   text step ever wraps it onto a row of its own, rather than letting it
   drift to the left under the logo. */
.header-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 0.9rem;
  margin-left: auto;
}

/* Get Help: the service-user action, and the one thing on the page a visitor
   in need should find without looking (Abi Revision Round, Step 2). It takes
   whatever space the logo and the actions leave and centres itself in it, so
   on desktop it sits in the middle of the header rather than as one of three
   buttons at the edge. Deliberately larger than Donate — the two used to be
   the same size, which gave supporting and being supported equal weight. */
.header-help {
  display: flex;
  flex: 1 1 auto;
  justify-content: center;
}

/* Scoped through .header-help for the same cascade reason as the
   .header-actions rules below. */
.header-help .header-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 3.25rem;
  padding: 0.5em 1.6em;
  font-size: var(--step-1);
  font-weight: 600;
  white-space: nowrap;
}

.header-help .header-cta .icon {
  width: 26px;
  height: 26px;
}

.site-nav {
  flex-basis: 100%;
}

/* Nav breakpoint — 52rem, NOT the 40rem the rest of this file uses.

   The nav collapses to the Menu button later than everything else because it
   is the one component whose content grew. At 40rem it had six top-level
   items; it now has eight, and the row needs 680px of labels and separators
   before any spacing. Above the old 640px breakpoint that wrapped, and a
   wrapped row leaves a separator dot dangling at the end of the first line —
   CSS cannot know where a line broke, so the dot cannot be suppressed.

   52rem gives the row 801px at the breakpoint against the 680px it needs, and
   it still fits at the accessibility toolbar's 112.5% step. At 125% it wraps
   between 832 and 890px, which is the same behaviour the six-item nav already
   had at that text size and is accepted for the same reason.

   Deliberately reusing 52rem rather than inventing a value: .split already
   breaks there. Only the three nav-only blocks moved — the
   header layout rules around them stay at 40rem, because the logo, phone
   number and CTAs did not change size. */
@media (min-width: 52.0625rem) {
  .site-nav {
    padding-top: 0.6rem;
    border-top: 1px solid var(--color-line);
  }
}

/* Wherever the Menu button exists, Get Help takes a full-width row of its own
   directly under the logo and Menu, and phone and Donate share the row below
   it, one at each end. A full-width bar is the most central position the
   header has at these widths, and on a phone it is also the biggest target. */
@media (max-width: 52rem) {
  .header-help {
    flex-basis: 100%;
  }

  .header-help .header-cta {
    flex: 1 1 auto;
  }

  .header-actions {
    flex-basis: 100%;
    justify-content: space-between;
  }
}

/* The band just above the nav breakpoint, where logo, Get Help and the
   actions do not all fit on one row. Left to wrap on its own, the actions
   dropped to a second row and Get Help stretched across the space beside the
   logo, landing up to 240px right of centre. Instead the actions stay up on
   the logo's row and Get Help takes the row beneath, centred.

   The single-row widths were measured, not estimated: 859px at default text,
   957 / 1056px at the toolbar's two larger steps, and 974 / 1087 / 1200px
   with Readable font on as well. Media queries cannot see the toolbar's
   classes, so each step carries its own upper bound, a little above its
   measured width. Re-measure if the logo, the name or either button changes
   size. */
@media (min-width: 52.0625rem) and (max-width: 55rem) {
  .header-help {
    order: 1;
    flex-basis: 100%;
  }

  .site-nav {
    order: 2;
  }
}

@media (min-width: 52.0625rem) and (max-width: 62rem) {
  html.a11y-text-lg .header-help,
  html.a11y-readable .header-help {
    order: 1;
    flex-basis: 100%;
  }

  html.a11y-text-lg .site-nav,
  html.a11y-readable .site-nav {
    order: 2;
  }
}

@media (min-width: 52.0625rem) and (max-width: 67rem) {
  html.a11y-text-xl .header-help {
    order: 1;
    flex-basis: 100%;
  }

  html.a11y-text-xl .site-nav {
    order: 2;
  }
}

@media (min-width: 52.0625rem) and (max-width: 69rem) {
  html.a11y-readable.a11y-text-lg .header-help {
    order: 1;
    flex-basis: 100%;
  }

  html.a11y-readable.a11y-text-lg .site-nav {
    order: 2;
  }
}

@media (min-width: 52.0625rem) and (max-width: 76rem) {
  html.a11y-readable.a11y-text-xl .header-help {
    order: 1;
    flex-basis: 100%;
  }

  html.a11y-readable.a11y-text-xl .site-nav {
    order: 2;
  }
}

/* Set at reading size rather than as small print: for a visitor who cannot
   navigate the site, or cannot read it, the phone number IS the service. */
.header-phone {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--color-primary-deep);
  text-decoration: none;
  white-space: nowrap;
}

.header-phone:hover {
  text-decoration: underline;
}

.header-phone .icon {
  width: 22px;
  height: 22px;
}

/* Scoped through .header-actions deliberately: these rules override .button,
   which is defined further down the file, so matching its specificity would
   lose on cascade order. */
.header-actions .header-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  padding: 0.5em 1em;
  font-weight: 600;
  white-space: nowrap;
}

.header-actions .header-cta .icon {
  width: 22px;
  height: 22px;
}

@media (max-width: 40rem) {
  /* Four stacked rows of near-identical weight is what made this read as
     cramped. Tightening the gap between them buys back some of what the 44px
     targets below cost, without touching the rows themselves. */
  .site-header__inner {
    gap: 0.75rem;
    padding-block: 0.75rem;
  }

  /* 44px on both. The phone number is a 32px inline link at its natural
     height, and the code comment above calls it the thing that IS the service
     for a visitor who cannot navigate or read the site — so it is the last
     target on the page that should be awkward to hit. Donate was 42px and
     only needs the two.

     Phone and Donate share a row now that Get Help has moved out of this
     cluster. Donate grows into the space the number leaves, capped so it
     never outweighs the full-width Get Help above it. The row wraps if a
     large text step makes the pair too wide for a narrow phone. */
  .header-phone {
    min-height: 2.75rem;
  }

  .header-actions .header-cta {
    flex: 1 0 auto;
    max-width: 12rem;
    min-height: 2.75rem;
  }
}

/* Height-constrained so the header bar stays a consistent depth whatever the
   artwork's proportions. Raised from 3.75/4.5rem: at the old size the logo
   read as an afterthought (Abi Revision Round, Step 1).

   The PNG has an opaque white ground, which showed as a pale box against the
   warm off-white base. `multiply` drops the white out so the artwork sits
   directly on the page. Safe in contrast mode too — that paints the base
   pure white, and white multiplied by white is unchanged. */
.brand__logo {
  display: block;
  flex-shrink: 0;
  width: auto;
  height: 3.75rem;
  mix-blend-mode: multiply;
}

@media (min-width: 40em) {
  .brand__logo {
    height: 6rem;
  }
}

/* --color-line, which this used to take, measures 1.37:1 against the base —
   the token block above says as much, and says that anything a visitor has to
   find and operate takes --color-line-strong (3.7:1) instead. This is the
   control that opens the navigation on every phone, so it is exactly the case
   that rule was written for; it was the one place the rule had not been
   applied. No desktop consequence either way: this button is `display: none`
   above 52rem and is only ever revealed by the collapsed-nav query below. */
.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.45rem;
  /* 44px. This is the control the whole site's navigation hangs off on a
     phone, and it was 40px. */
  min-height: 2.75rem;
  padding-inline: 0.9rem;
  font: inherit;
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius);
  cursor: pointer;
}

.nav-toggle .icon {
  width: 22px;
  height: 22px;
}

/* Open state. The button carried `aria-expanded` but looked identical either
   way, so the only person who could tell the menu was open was someone using
   assistive tech. Filled rather than merely outlined, because the difference
   has to survive being glanced at: white on --color-primary is 6.9:1, and the
   lifted gold on the middle bar 3.7:1 against the same fill. */
.nav-toggle[aria-expanded="true"] {
  background: var(--color-primary);
  color: var(--color-accent-text);
  border-color: var(--color-primary);
}

/* Contrast mode flattens icons to dark ink assuming a light ground (see
   `html.a11y-contrast .icon`), which would paint this one out against the
   fill. Same override the drop-in card needs, for the same reason. */
.nav-toggle[aria-expanded="true"] .icon,
html.a11y-contrast .nav-toggle[aria-expanded="true"] .icon {
  --icon-stroke: currentColor;
  --icon-accent: var(--color-gold-on-dark);
}

.site-nav__list {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--space) * 1.25);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Scoped to direct children so sublist links do not inherit the underline. */
.site-nav__list > li > a {
  text-decoration: none;
  color: var(--color-text);
  padding-block: 0.25em;
  border-bottom: 2px solid transparent;
}

.site-nav__list > li > a:hover,
.site-nav__list > li > a[aria-current="page"] {
  border-bottom-color: var(--color-accent);
}

.site-nav__sublist {
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-nav__sublist a {
  text-decoration: none;
  color: var(--color-text);
}

.site-nav__sublist a:hover,
.site-nav__sublist a[aria-current="page"] {
  text-decoration: underline;
}

/* Above the mobile breakpoint the sublist becomes a dropdown. :focus-within
   keeps it reachable by keyboard without any JS. */
@media (min-width: 52.0625rem) {
  /* The nav has its own full-width row now, so a fixed gap left the whole
     right-hand half empty. The items spread across it instead, divided by a
     dot rather than by a rule — the row already sits under a hairline border,
     and a second set of vertical lines would read as a table. */
  .site-nav__list {
    gap: 0;
  }

  .site-nav__item {
    display: flex;
    align-items: center;
    flex: 1 1 auto;
  }

  /* The last item does not grow, so the row ends flush against the right edge
     instead of trailing off into its share of the free space. */
  .site-nav__item:last-child {
    flex: 0 0 auto;
  }

  /* Centred in the gap, not hung off the label: the two auto margins split
     this item's share of the free space equally on either side of the dot,
     which lands it exactly midway between the two labels however the space is
     distributed. Empty content, so screen readers never announce it. */
  .site-nav__item:not(:last-child)::after {
    content: "";
    flex: none;
    width: 0.375rem;
    height: 0.375rem;
    margin-inline: auto;
    border-radius: 50%;
    background: var(--color-primary);
  }

  .site-nav__item.has-children {
    position: relative;
  }

  /* Hidden with visibility rather than `display: none`, which is what made
     this snap — display is not an animatable property, so there was nothing
     for a transition to act on.

     visibility does everything display did that matters here: it takes the
     panel out of the accessibility tree AND out of the tab order, so the
     child links stay unreachable until the parent is hovered or focused.
     Nothing is traded away for the animation. The keyboard path is unchanged
     too — focus lands on the parent link, that triggers :focus-within on the
     li, and the children become focusable before the next Tab. */
  .site-nav__sublist {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 5;
    min-width: 12rem;
    padding-block: 0.4rem;
    background: var(--color-bg);
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    /* A little more lift than the card hover shadow: this panel genuinely
       floats over the content below, where a card only nudges. */
    box-shadow: 0 10px 24px rgba(19, 48, 41, 0.12);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-0.35rem);
  }

  .site-nav__item.has-children:hover .site-nav__sublist,
  .site-nav__item.has-children:focus-within .site-nav__sublist {
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  @media (prefers-reduced-motion: no-preference) {
    /* visibility is a stepped property, not an interpolated one, so it needs
       driving by hand from both sides: delayed to the end of the fade on the
       way out, immediate on the way in. Without that the panel would either
       disappear before it had faded, or linger in the tab order after it had.

       Transform runs slightly longer than opacity so the panel is still
       settling as it finishes appearing, which is what reads as "smooth"
       rather than as two properties finishing on the same frame. The easing
       is the same curve as the hero, so the site moves one way throughout. */
    .site-nav__sublist {
      transition: opacity 150ms ease,
        transform 180ms cubic-bezier(0.2, 0.7, 0.3, 1),
        visibility 0s linear 150ms;
    }

    .site-nav__item.has-children:hover .site-nav__sublist,
    .site-nav__item.has-children:focus-within .site-nav__sublist {
      transition: opacity 150ms ease,
        transform 180ms cubic-bezier(0.2, 0.7, 0.3, 1),
        visibility 0s;
    }
  }

  .site-nav__sublist a {
    display: block;
    padding: 0.35em 0.9em;
  }
}

@media (max-width: 52rem) {
  /* Both the toggle and the collapse are gated on `html.js`, which the inline
     script in base.njk adds before first paint.

     Without that gate this was the one part of the site that did not degrade.
     The collapse was unconditional and only main.js ever adds `.is-open`, so
     if that script failed to load a phone visitor got a dead Menu button and
     no navigation at all — the footer sitemap was the only route left. The
     support dialog and the translate widget both fall back to something that
     works; this now does too. No JS means no toggle and the nav rendered open
     as a plain stacked list, which is the correct fallback and the state the
     mobile list styles below were already written for.

     Above 52rem none of this applies: the toggle stays `display: none` from
     its base rule and the nav is never collapsed. */
  html.js .nav-toggle {
    display: inline-flex;
  }

  /* flex-basis is set unconditionally further up — only the collapse is
     mobile-specific. */
  html.js .site-nav {
    display: none;
  }

  html.js .site-nav.is-open {
    display: block;
  }

  /* The menu opens a row below the phone number and the two CTAs, roughly
     100px from the button that opened it, which is far enough to read as
     unrelated to it. The rule ties it back to the header: it is the same
     hairline the nav row carries above the breakpoint, so the panel reads as
     part of the header rather than as the start of the page.

     The nav is NOT moved above the actions to close that gap, which was the
     other option. Doing it needs `order`, and `order` changes only the visual
     sequence — tab order would still run button, phone, CTAs, then back up to
     the links, which trades a layout annoyance for a focus-order defect. */
  .site-nav {
    border-top: 1px solid var(--color-line);
  }

  .site-nav__list {
    flex-direction: column;
    gap: 0;
    padding-block: 0.5rem;
  }

  /* Full-width rows at 44px. These were ~28px inline links with 8px between
     them — they scraped past the 24px minimum on the spacing exception and no
     more, in the one menu on the site that is only ever operated by thumb.

     The current-page marker moves from an underline to a leading rule for the
     same change: on a stacked list a full-width underline reads as a divider
     between items rather than as a mark on one of them. */
  .site-nav__list > li > a {
    display: flex;
    align-items: center;
    min-height: 2.75rem;
    padding-block: 0;
    padding-left: 0.7rem;
    border-bottom: 0;
    border-left: 3px solid transparent;
  }

  .site-nav__list > li > a:hover,
  .site-nav__list > li > a[aria-current="page"] {
    border-left-color: var(--color-accent);
  }

  /* Inline and indented on mobile rather than a dropdown, so every link is
     reachable with the menu open. The rule down the left is the same way the
     footer's site map marks nesting. */
  .site-nav__sublist {
    margin-top: 0;
    margin-left: 0.7rem;
    padding-left: var(--space);
    border-left: 1px solid var(--color-line);
  }

  .site-nav__sublist li {
    margin-bottom: 0;
  }

  /* The smallest targets on the site — no vertical padding at all. */
  .site-nav__sublist a {
    display: flex;
    align-items: center;
    min-height: 2.75rem;
  }
}

/* Announcement strip ------------------------------------------------------ */

/* Karen's togglable sitewide notice. Sits between the header and the content,
   and exists only while she has it switched on.

   Gold wash with a rule top and bottom, rather than a solid blue slab. The
   design system allows one loud block per page and on most pages that is
   already spoken for — the drop-in card on the homepage, the urgent-items
   callout on Donating Goods. A notice that shouted louder than the page's own
   main message would invert the two. Gold is also the site's "pay attention
   to this" hue everywhere else, so the strip reads as flagged, not as an
   error state.

   The borders are doing real work, not decoration. Contrast mode re-points
   --color-gold-soft to #ffffff, which is also its --color-bg — so with a
   background alone the strip would vanish into the page for exactly the
   visitors who most need to find it. --color-line-strong follows contrast
   mode down to near-black, so the band stays a band. */
.announcement {
  background: var(--color-gold-soft);
  border-block: 1px solid var(--color-line-strong);
}

.announcement__inner {
  display: flex;
  /* Wraps for a long message at 125% text on a narrow phone. */
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 0.75rem;
  padding-block: 0.7rem;
}

/* 24px against the 32px default: this sits beside a single line of body copy,
   not above a heading, so it marks the strip without becoming its subject. */
.announcement .icon {
  width: 24px;
  height: 24px;
}

.announcement__text {
  /* Beats the global `p { margin: 0 0 1em }`, which would otherwise leave a
     ragged gap under the only line in the strip. */
  margin: 0;
  /* min-width:0 lets a long message wrap inside the flex row instead of
     forcing the row wider than the viewport. */
  min-width: 0;
  flex: 1 1 16rem;
  font-weight: 600;
}

/* Components -------------------------------------------------------------- */

.button {
  display: inline-block;
  padding: 0.6em 1.4em;
  background: var(--color-accent);
  color: var(--color-accent-text);
  text-decoration: none;
  border-radius: var(--radius);
}

/* Supporter-facing actions only, so giving never looks like a service. Gold
   is light enough that the inherited white text would fail contrast against
   it, so this pairs it with the dark blue-grey instead (4.7:1). */
.button--warm {
  background: var(--color-warm);
  color: var(--color-text);
}

.button:hover {
  background: var(--color-primary-deep);
}

.button--warm:hover {
  background: var(--color-gold-deep);
  color: var(--color-accent-text);
}

/* A button carrying an icon beside its label. Kept as a modifier rather than
   folded into .button: most buttons on the site are text only, and switching
   the base class to inline-flex would change how those sit on a line of
   prose. */
.button--icon {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.button--icon .icon {
  width: 22px;
  height: 22px;
}

/* Homepage ---------------------------------------------------------------- */

.hero-home {
  position: relative;
  overflow: hidden;
  padding-block: calc(var(--space) * 4);
  background: var(--color-accent-deep);
  color: var(--color-accent-text);
}

/* 64px top and bottom is generous air around type that has just come down to
   26px, and it is spent at the worst point on the page: the drop-in card — the
   one block that has to be found — already starts around 720px down a phone.
   40px gives 48px of that back. */
@media (max-width: 40rem) {
  .hero-home {
    padding-block: calc(var(--space) * 2.5);
  }
}

/* Light falling from the upper left, so the block reads as lit, not flat. */
.hero-home::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    60rem 40rem at 15% -10%,
    rgba(255, 255, 255, 0.14),
    transparent 70%
  );
}

.hero-home__inner {
  position: relative;
  max-width: 52rem;
}

.hero-home__eyebrow {
  margin-bottom: 0.75rem;
  font-size: 0.85rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  /* Raised from 0.72. At small uppercase sizes this is the only text in the
     hero held to the 4.5:1 threshold, and 0.72 left it at 4.64:1 against the
     lit gradient — no headroom for anything layered behind it. 0.85 keeps it
     passing even where the gradient peak and the watermark would coincide. */
  color: rgba(255, 255, 255, 0.85);
}

.hero-home__strapline {
  margin-bottom: calc(var(--space) * 1.75);
  font-size: var(--step-display);
  line-height: 1.1;
  text-wrap: balance;
}

.verse {
  margin: 0;
  padding-left: var(--space);
  border-left: 2px solid rgba(255, 255, 255, 0.35);
}

.verse blockquote {
  margin: 0;
}

.verse blockquote p {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-style: italic;
  color: rgba(255, 255, 255, 0.92);
}

.verse figcaption {
  margin-top: 0.4rem;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.65);
}

/* Drop-in ----------------------------------------------------------------- */

/* The service-user entry point, and the one block on the page that has to
   survive being skimmed by someone who cannot read it. Three things do that
   work: a solid fill rather than a tint (so it reads as an object, not a
   paragraph), the door icon beside the heading, and hours set larger than the
   hero strapline.

   Gold is the accent everywhere else and never a background — so this takes
   the blue, and the gold appears only on the top edge and inside the icon. */
.dropin-zone {
  padding-block: calc(var(--space) * 2.5);
}

.dropin {
  padding: calc(var(--space) * 1.75) calc(var(--space) * 1.5);
  background: var(--color-primary);
  color: var(--color-accent-text);
  /* White on this blue is 6.9:1, so every size of text inside clears AA. */
  border-top: 5px solid var(--color-gold);
  border-radius: var(--radius);
}

.dropin__head {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin-bottom: 0.35rem;
}

/* Deliberately larger than the 32px wayfinding icons in the cards below: this
   one is doing more than anchoring a heading, it is the mark a visitor who
   cannot read the heading is meant to find. */
.dropin .icon {
  width: 3rem;
  height: 3rem;
  --icon-stroke: var(--color-accent-text);
  --icon-accent: var(--color-gold-on-dark);
}

/* Contrast mode flattens icons to dark ink on the assumption of a light
   ground (see `html.a11y-contrast .icon`), which on this panel would paint
   them out entirely. That rule carries a type selector, so beating it needs
   one here too rather than relying on the rule above. */
html.a11y-contrast .dropin .icon {
  --icon-stroke: var(--color-accent-text);
  --icon-accent: var(--color-gold-on-dark);
}

.dropin__title {
  margin: 0;
  color: inherit;
}

.dropin__sub {
  margin: 0 0 0.75rem;
  font-size: var(--step-1);
}

/* The single largest thing on the homepage, per Section 1 — a visitor who
   reads nothing else should still come away with the days and the times. */
.dropin__hours {
  margin: 0 0 0.75rem;
  font-family: var(--font-display);
  font-size: var(--step-hours);
  font-weight: 600;
  line-height: 1.1;
  text-wrap: balance;
}

/* At this size the times will break mid-range across a phone column
   otherwise, which is exactly the string that must not be misread. */
.dropin__times {
  white-space: nowrap;
}

.dropin__address {
  margin-bottom: 0.75rem;
  font-size: var(--step-1);
  font-style: normal;
}

.dropin__close {
  margin: 0;
  font-size: var(--step-1);
}

/* Opens the support dialog, and is built to look like "Get Help" in the
   header that does the same: same label, shape, weight and door icon. Gold
   rather than that button's blue, which would disappear into the card's own
   blue — chosen by Oscar, and the one service-user action that wears the gold
   the site otherwise keeps for supporters. Dark text on it for the same
   contrast reason as .button--warm (4.7:1). */
.dropin__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 3.25rem;
  margin-top: 1.25rem;
  padding: 0.5em 1.6em;
  background: var(--color-gold);
  color: var(--color-text);
  font-size: var(--step-1);
  font-weight: 600;
}

.dropin__cta:hover {
  background: var(--color-gold-deep);
  color: var(--color-accent-text);
}

/* Beats both `.dropin .icon` (3rem, white strokes for the blue panel) and
   `.button .icon` (currentColor throughout). The door's lines follow the
   label; its light goes white, since a gold light on a gold button vanishes. */
.dropin .dropin__cta .icon,
html.a11y-contrast .dropin .dropin__cta .icon {
  width: 26px;
  height: 26px;
  --icon-stroke: currentColor;
  --icon-accent: var(--color-accent-text);
}

/* Support dialog ---------------------------------------------------------- */

/* Wears the .dropin panel outright, so the modal behind "Get support" and the
   card on the homepage cannot drift apart — a visitor who has seen one should
   recognise the other rather than have to read it again. Everything here is
   either positioning or the handful of places where sitting on a blue ground
   changes what a default can be. */
.support-dialog {
  width: min(34rem, calc(100vw - 2rem));
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-accent-text);
}

.support-dialog::backdrop {
  background: rgba(12, 26, 40, 0.7);
}

.support-dialog__panel {
  position: relative;
}

/* Clear of the close button, which sits in the same corner. */
.support-dialog__panel .dropin__head {
  padding-right: 2.75rem;
}

.support-dialog__close {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44px. It is the only control in the dialog, and the people most likely to
     open it are on a phone. */
  width: 2.75rem;
  height: 2.75rem;
  font-family: var(--font-body);
  font-size: 1.75rem;
  line-height: 1;
  color: var(--color-accent-text);
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: var(--radius);
  cursor: pointer;
}

.support-dialog__close:hover {
  background: rgba(255, 255, 255, 0.16);
}

/* Every link in here would otherwise be --color-accent, which is the same
   blue as the panel behind it. Underlined as well as re-coloured: on a
   coloured ground, colour alone is not enough to mark a link. */
.support-dialog__panel a {
  color: var(--color-accent-text);
  text-decoration: underline;
}

.support-dialog__phone {
  margin: 0 0 0.6rem;
  font-size: var(--step-1);
  font-weight: 600;
}

.support-dialog__phone a {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

/* `.dropin .icon` sizes the door at 3rem, and this panel carries the .dropin
   class, so the phone icon has to be brought back down here. */
.support-dialog__phone .icon,
html.a11y-contrast .support-dialog__phone .icon {
  width: 24px;
  height: 24px;
  --icon-stroke: var(--color-accent-text);
  --icon-accent: var(--color-gold-on-dark);
}

.support-dialog__more {
  margin: 0;
  font-size: 0.95rem;
}

/* The 3fr/1fr split. Stacks on narrow screens, service-user column first. */
.split {
  display: grid;
  gap: calc(var(--space) * 2.5);
  padding-block: calc(var(--space) * 3);
}

@media (min-width: 52rem) {
  .split {
    grid-template-columns: 3fr 1fr;
    gap: calc(var(--space) * 3);
  }
}

/* Support routes ---------------------------------------------------------- */

/* The service-user routes inside the "Get support" dialog (Content
   Expansion Blueprint Step 5).

   Full-width bordered rows rather than inline links. On a blue ground an
   inline link can only be marked by underline and colour, and four of them
   stacked read as a paragraph of links; a bordered row reads as a door. It
   also gives a target the width of the panel, which is the difference between
   a confident tap and a careful one for someone using this in a hurry.

   The underline that .support-dialog__panel puts on every link is dropped
   here on purpose, and it is not a contrast regression: that rule exists
   because colour alone cannot distinguish a link from the text around it
   (WCAG 1.4.1). These are not in a run of text — they are bordered, padded,
   icon-led blocks, distinguished by shape rather than by colour, so the
   requirement is met without the underline. Hover and focus both change more
   than colour too. */
.support-routes {
  margin-block: 1rem 1.25rem;
}

.support-routes__title {
  margin: 0 0 0.5rem;
  font-size: var(--step-1);
  color: inherit;
}

.support-routes__list {
  display: grid;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.support-routes__list a {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  /* 44px minimum without relying on the text to produce it, so the row is the
     same size whether its label wraps or not. */
  min-height: 2.75rem;
  padding: 0.45rem 0.8rem;
  font-size: var(--step-1);
  font-weight: 600;
  text-decoration: none;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: var(--radius);
}

.support-routes__list a:hover {
  background: rgba(255, 255, 255, 0.16);
  border-color: var(--color-accent-text);
}

/* Sized down from the 3rem the .dropin rule gives icons in this panel: that
   size is for the one mark at the top that has to be found without reading.
   At 3rem in a 44px row these would be the row. */
.support-routes__list .icon {
  width: 1.6rem;
  height: 1.6rem;
}

/* The focus ring, fixed for the whole blue panel ---------------------------
   The global :focus-visible outline is --color-accent, which resolves to
   --color-primary — the exact colour of this panel's background. So every
   focusable control inside it (the close button, the phone link, the contact
   link, and now these routes) had a focus ring painted in the background
   colour: invisible, on the one component on the site that traps focus.

   White measures 6.9:1 against this blue, well past the 3:1 that WCAG 2.4.11
   asks of a focus indicator. Scoped to .dropin rather than to the dialog, so
   any link added to the homepage card inherits the fix too. */
.dropin :focus-visible {
  outline-color: var(--color-accent-text);
}

/* Icons ------------------------------------------------------------------- */

/* Two-tone: blue carries the outline, gold picks out one detail. Set as
   custom properties so contrast mode and hover re-colour both halves
   together, and so an icon dropped into a dark panel can be flipped by
   setting two values rather than restyling paths. */
.icon {
  --icon-stroke: var(--color-primary);
  /* The deeper gold, not --color-gold: a small detail inside a 24px glyph
     needs more contrast than a button fill does. The bright gold measures
     2.8:1 against the base, under the 3:1 floor for meaningful graphics, and
     it cannot be darkened at source without pushing the CTA's dark-on-gold
     text below 4.5:1 — the two constraints cross, so they take separate
     steps of the same hue. */
  --icon-accent: var(--color-gold-deep);
  display: block;
  flex: none;
}

/* Sits above the heading on a card, sized to anchor the text without
   competing with it. */
.pathway .icon,
.card .icon {
  margin-bottom: 0.6rem;
}

/* Icons inside a button take the button's own colour rather than the two-tone
   pair. On a filled ground at 22px the gold half muddies, and currentColor
   means the icon follows the label through hover and through contrast mode
   without a rule for each. The type selector is there to beat
   `html.a11y-contrast .icon`, which would otherwise flatten these to dark ink
   on the assumption of a light background. */
.button .icon,
html.a11y-contrast .button .icon {
  --icon-stroke: currentColor;
  --icon-accent: currentColor;
}

/* The exception: the door keeps its gold light on the support CTA. That
   detail is what makes the icon read as "open, come in" rather than as a
   door, and it is the one button on the site where that distinction is
   carrying real wayfinding weight. Lifted gold, because plain --color-gold
   only reaches 2.3:1 against the blue fill. */
.header-cta--support .icon,
html.a11y-contrast .header-cta--support .icon {
  --icon-accent: var(--color-gold-on-dark);
}

/* Icon-led subheading on inner pages. The icon is inside the heading but
   aria-hidden, so the heading's accessible name stays the text alone; the
   bare text node becomes an anonymous flex item beside it. Sized down from
   the homepage's 32px so it anchors the heading without outweighing it. */
/* `flex-start`, not `center`. Centring works only while the heading is one
   line; the moment it wraps, the icon parks halfway down the block with
   nothing beside it and stops reading as a mark on the title. That is not a
   narrow-screen case — "Information for Current Volunteers" measures 679px at
   the desktop h1 size against 651px of column, so it wraps at every width.

   The nudge below then centres the icon on the first line's CAP BAND rather
   than on its line box, which is what the eye reads as aligned. A line box
   carries descender space the capitals never reach, so a box-centred icon sits
   noticeably high — about 5px on the h1s.

   The arithmetic, once, for all four cases: at line-height 1.2 the half-
   leading is 0.1em, and both font stacks put the cap top 0.278em below that
   (0.978em ascender less 0.700em cap height) with the caps 0.700em deep — so
   the cap band centres 0.728em below the top of the line box. Subtracting half
   the icon gives the offset.

   Written as `calc(0.728em - <half the icon>)` rather than a resolved number
   because the em term tracks the heading while the icon stays a fixed size, so
   only this form stays exact across the fluid mobile scale as well as here. */
.h-icon {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
}

.h-icon .icon {
  width: 26px;
  height: 26px;
  margin-top: calc(0.728em - 13px);
}

/* The dove leading a page title. Deliberately larger than the 26px
   wayfinding icons on the h2s below it: at the same size it would read as
   another section marker rather than as the identity mark. The size difference is what keeps the two roles
   apart, so it should stay noticeably bigger than the h2 icons.

   Solid, not the 10% watermark tint. At this size a wash would look like a
   half-loaded image; the mark earns its place here by being a deliberate part
   of the title, not a background.

   Larger than the 2.6rem the cathedral had. The dove is wide rather than
   tall — it fills the square's width but only about 60% of its height — so
   at the old size it stood ~25px high beside a 40px title and read as a
   scribble (Abi Revision Round, Step 6). */
h1.h-icon {
  gap: 0.7rem;
}

h1.h-icon .icon {
  width: 3.4rem;
  height: 3.4rem;
  margin-top: calc(0.728em - 1.7rem);
}

/* Sizes only — the alignment is handled once in the base rules above, and the
   `calc(0.728em - half)` form carries over unchanged. */
@media (max-width: 40rem) {
  /* 26px against 28px of heading was already marginal; against 23px it starts
     to outweigh the words it is meant to be anchoring. */
  .h-icon .icon {
    width: 22px;
    height: 22px;
    margin-top: calc(0.728em - 11px);
  }

  /* Still clearly the larger of the two, which is the whole point of the size
     difference — the dove is the identity mark, the 22px glyphs above are
     section markers. Left at 2.2rem when the desktop size went up for the
     dove: "Communications" (see the mobile type scale) already fills a 360px
     phone at the largest text step, and 2.6rem pushed it off a 390px one too.
     2.2rem is the ceiling. */
  h1.h-icon .icon {
    width: 2.2rem;
    height: 2.2rem;
    margin-top: calc(0.728em - 1.1rem);
  }
}

/* Page titles that are a single long word. "Communications" cannot wrap, so
   on a phone at the toolbar's larger text steps it runs off the edge — at the
   largest step it no longer fits even a 390px screen once the title mark
   takes its share of the line. Hyphenating lets it break properly
   ("Communi-cations") rather than being clipped.

   Scoped to exactly that case. `hyphens: auto` also hyphenates words that
   would have fitted on the next line, so applied everywhere it would start
   splitting ordinary multi-word titles at default sizes. `break-word` is the
   backstop for a browser without an English hyphenation dictionary: an
   unhyphenated break still beats text off the screen.

   `h1.h-icon` has to leave flex layout for this to work. There the title text
   is an anonymous flex item, which is sized to its longest word and cannot be
   given `min-width: 0`, so the word never gets a chance to break. In normal
   inline flow the mark sits at the start of the first line and the text
   wraps after it. */
@media (max-width: 40rem) {
  html.a11y-text-lg h1,
  html.a11y-text-xl h1 {
    hyphens: auto;
    overflow-wrap: break-word;
  }

  html.a11y-text-lg h1.h-icon,
  html.a11y-text-xl h1.h-icon {
    display: block;
  }

  html.a11y-text-lg h1.h-icon .icon,
  html.a11y-text-xl h1.h-icon .icon {
    display: inline-block;
    margin: 0 0.5rem 0 0;
    vertical-align: -0.35em;
  }
}

/* Watermark --------------------------------------------------------------- */

/* Hidden by default rather than shrunk: below this width the copy fills the
   column, so there is nowhere for the mark to sit that is not behind text.
   Above it there is genuine clear space beside the reading column. */
.watermark {
  display: none;
}

/* Everything here is positioned so the mark is drawn WHOLE. The first attempt
   bled it off the container edges, which works for a photograph or a texture
   but not for this: it is a line drawing, and a dove with its wingtip or its
   tail sliced off stops reading as a deliberate mark and starts reading as a
   broken image. (Written for the cathedral this replaced, whose spires and
   ground line were the load-bearing parts; the principle carries over.)

   It is also positioned against the content grid rather than the container
   box — each variant sits inside a `.wrap`, so `right: 0` lands on the same
   line the text column ends on. Floating it against the raw section box is
   what made it look dropped in at random. */
@media (min-width: 60em) {
  .watermark {
    display: block;
    position: absolute;
    pointer-events: none;
    /* 10% throughout. Measured ceiling is 15%: at that point muted text over
       a stroke drops to 4.48:1 on --color-surface and stops clearing AA. */
    opacity: 0.1;
  }

  /* `.icon` sets these custom properties on itself, so an override has to beat
     that selector rather than rely on inheritance from the wrapper. */
  .watermark .icon {
    width: 20rem;
    height: 20rem;
  }

  /* Whole, like the rest. The argument that a full-bleed band could carry a
     bleeding mark was wrong: a cut-off mark looks like a clipped image here
     too.

     No inset is needed on either axis. The dove runs almost the full width
     of the 24-unit viewBox (ink from x 0.3 to 23.7) but only y 4.4 to 19.4,
     so `right: 0; bottom: 0` leaves a small side gutter and a generous one
     below, and the mark does not jam against the band edge. */
  .watermark--hero {
    right: 0;
    bottom: 0;
  }

  /* Smaller than the 20rem default until there is room for it. The hero copy
     column is 52rem and centred, so the clear space beside it is
     (viewport - 52rem) / 2 — only 4rem at this breakpoint, and a full-size
     mark would sit well under the strapline rather than beside it. */
  .watermark--hero .icon {
    width: 15rem;
    height: 15rem;
  }

  /* Single tone on the dark ground: at 10% the blue/gold split stops reading
     as two-tone and only muddies the mark. */
  .watermark--hero .icon {
    --icon-stroke: #ffffff;
    --icon-accent: #ffffff;
  }

  /* Bottom right corner of the band itself. Anchored to the bottom, which
     suited the cathedral this replaced (it stood on a ground line) and still
     suits the dove: growing upward it runs into the band's 3rem top padding,
     which is free space, so nothing clips. 9rem keeps it clear of the top
     edge even when the vision and mission statements are short. */
  .watermark--tenets {
    right: 0;
    bottom: 0;
  }

  .watermark--tenets .icon {
    width: 9rem;
    height: 9rem;
  }

  /* Bottom left, which is the placement that was working — it was only the
     clipping that was wrong. It sat well short of the corner at `bottom: 3rem`
     and read as floating rather than seated, so it now settles into the corner
     itself.

     The offsets were set for the cathedral this replaced and kept for the
     dove, which sits comfortably inside them. At 12rem one viewBox unit is
     8px; the dove's ink runs from x 0.3 (the far wingtip, ~3px from the left
     edge) and stops at y 19.4, so it floats ~29px above the container's
     bottom edge with `bottom: -0.5rem`. No ink crosses the container box,
     so the footer's `overflow: hidden` clips nothing. Do not push `left`
     negative: the wingtip is the first thing it would cut.

     Sinking past the legal rule is fine — that rule lives inside `.wrap`, and
     the mark ends around 181px, well left of where the wrap's content
     begins. */
  .watermark--footer {
    left: 0;
    bottom: -0.5rem;
  }

  .watermark--footer .icon {
    width: 12rem;
    height: 12rem;
  }

  /* `page` is handled separately below — .prose narrows its wrap to 44rem, so
     `right: 0` would land the mark on the text rather than beside it. */
}

/* The hero mark on a phone -----------------------------------------------
   The blanket `display: none` above reasons that below 60em the copy fills the
   column and there is nowhere for the mark to sit that is not behind text.
   That holds for the tenets band, but not here: the verse runs about a line
   and a half and its caption is four words, so the bottom right corner of this
   hero is the emptiest region on the page.

   Where it does fall behind the verse, that is a watermark doing what a
   watermark does, and the contrast work is already banked — the eyebrow note
   above records the alpha being lifted to 0.85 specifically so the small text
   here clears 4.5:1 "even where the gradient peak and the watermark would
   coincide". White at 10% on this ground is the case that was measured.

   8.5rem, not the 15rem the mark takes at the desktop end of the same corner:
   at 390px that is already 35% of the width, and the artwork carries its own
   margin inside the viewBox so `right: 0; bottom: 0` still leaves a gutter.

   Scoped to 40rem to match every other mobile rule in this file, which does
   leave 640-960px with no mark at all — the same gap the tenets and footer
   variants have always had in that range. */
@media (max-width: 40rem) {
  .watermark--hero {
    display: block;
    position: absolute;
    right: 0;
    bottom: 0;
    pointer-events: none;
    opacity: 0.1;
  }

  /* Single tone, for the reason the desktop rule gives: at 10% the blue/gold
     split stops reading as two-tone and only muddies the mark. */
  .watermark--hero .icon {
    width: 8.5rem;
    height: 8.5rem;
    --icon-stroke: #ffffff;
    --icon-accent: #ffffff;
  }
}

/* The footer mark on a phone ---------------------------------------------
   Phone only; the desktop placement above is untouched. On a phone the footer
   stacks into one column with every block's text running down the left, so
   the desktop's bottom-left corner would sit under the text. The clear space
   is on the RIGHT: beside the short social links and above the legal line.
   So it moves to the bottom right corner, the same corner the hero mark
   takes on a phone.

   9rem: big enough to read as the dove at 390px, small enough to stay in the
   empty side of the column. Two-tone like the desktop footer mark, which
   also sits on the light surface. Same 10% as everywhere else.

   Raised clear of the legal line rather than seated in the corner: at
   bottom: 0 the line cut through the dove's body. On a phone that line sits
   about 5.1rem above the bottom of the footer at every width, and it scales
   with the accessibility text sizes, so the offset is in rem. The dove's
   ink stops about 1.7rem above the bottom of its 9rem box, so 4.25rem leaves
   roughly 0.85rem between the lowest ink and the line. */
@media (max-width: 40rem) {
  .watermark--footer {
    display: block;
    position: absolute;
    right: 0.25rem;
    bottom: 4.25rem;
    pointer-events: none;
    opacity: 0.1;
  }

  .watermark--footer .icon {
    width: 9rem;
    height: 9rem;
  }
}

/* Contrast mode is a request for flat, maximal separation. A decorative wash
   behind text is precisely what it is asking to be rid of. */
html.a11y-contrast .watermark {
  display: none;
}

/* Callouts ---------------------------------------------------------------- */

/* Gold carrying real emphasis rather than decoration — a tinted panel with a
   solid gold edge. Still a wash rather than a fill, so body text keeps its
   contrast on top. */
/* The wash measures only 1.04:1 against the page base — light-on-light cannot
   reach 3:1 at all — so the rule, not the fill, is what identifies this as a
   distinct panel. That makes it a meaningful graphic rather than decoration,
   and it has to clear 3:1: the bright --color-gold sits at 2.80:1, so this
   uses a deeper step of the same hue (5.5:1). Reads as more emphatic gold,
   not less. */
.callout {
  margin-block: calc(var(--space) * 1.5);
  padding: calc(var(--space) * 1.25) calc(var(--space) * 1.5);
  background: var(--color-gold-soft);
  border-left: 4px solid var(--color-gold-deep);
  border-radius: var(--radius);
}

.callout > :last-child {
  margin-bottom: 0;
}

.callout .h-icon {
  margin-top: 0;
}

/* The urgent list reads as a scannable set of items rather than prose. */
.callout__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.4rem var(--space);
  margin: 0;
  padding: 0;
  list-style: none;
}

.callout__list li {
  padding-left: 1.4rem;
  position: relative;
}

/* Gold tick rather than a bullet, tying the list to the panel's edge. */
.callout__list li::before {
  content: "";
  position: absolute;
  left: 0.2rem;
  top: 0.55em;
  width: 0.5rem;
  height: 0.28rem;
  border-left: 2px solid var(--color-gold-deep);
  border-bottom: 2px solid var(--color-gold-deep);
  transform: rotate(-45deg);
}

/* Social activity sessions ------------------------------------------------ */

/* The drop-in timetable on Social Activities. Cards rather than a list,
   because the three things a visitor needs from each entry — what it is, when
   it happens, anything else — are read as a block, not as a sentence.

   One per row, in the order of the week. In the narrow text column two
   fitted side by side, so three sessions left the third alone on its own row.
   A single column reads as a timetable from Monday down, and stays tidy
   whatever number of sessions Karen adds or removes in the CMS.

   The day and time carry the emphasis rather than the name. Someone scanning
   this page has usually already decided they want to come and is looking for
   when — the same reasoning that sets the hours larger than everything else
   on the drop-in card. */
.sessions {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space);
  margin: 0 0 calc(var(--space) * 1.5);
  padding: 0;
  list-style: none;
}

.session {
  padding: calc(var(--space) * 1.1) calc(var(--space) * 1.25);
  background: var(--color-surface);
  /* A hairline is enough here: these sit on the page base as a set, and the
     gold edge is spoken for by the Brushstrokes callout further down. Two
     gold-edged panels on one page and neither reads as the emphatic one. */
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
}

.session__name {
  margin: 0 0 0.15rem;
  font-size: var(--step-1);
}

.session__when {
  margin: 0 0 0.35rem;
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--color-primary-deep);
}

.session__note {
  margin: 0;
  color: var(--color-muted);
}

/* The two channel buttons. Wraps to a stack on a phone rather than shrinking
   two buttons into an unreadable row. */
.channel-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

/* Advice and Support ------------------------------------------------------ */

/* The Friday advice session, inside the gold callout. Everything else on that
   page points somewhere else in Birmingham, so the one session that happens
   in this building is set larger than the referrals below it — the same
   reasoning that makes the hours the largest thing on the drop-in card,
   scaled to a panel rather than a page. */
.advice-when {
  margin: 0 0 0.6rem;
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.2;
  color: var(--color-primary-deep);
}

.advice-note {
  margin: 0.75rem 0 0;
  font-weight: 600;
}

/* The partnership credit. Quiet — it is provenance, not an instruction, and
   it sits directly under the line that IS one. */
.advice-partnership {
  margin: 0.2rem 0 0;
  font-size: 0.9rem;
  color: var(--color-muted);
}

/* Forces the shared .cards grid to a single column. Used where entries are
   long and uneven enough that auto-fit leaves one nearly empty cell beside a
   wall of text.

   Doubled class on purpose: the base .cards rule sits further down this
   file, so a single-class selector here loses to it and the stack never
   applied. */
.cards.cards--stack {
  grid-template-columns: 1fr;
}

/* Phone, email and website for each organisation. Rows rather than a comma
   run: these are three different actions, and on a phone each one has to be
   its own target. */
.org__contact {
  display: grid;
  gap: 0.35rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
}

.org__contact li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.org__contact .icon {
  width: 1.15rem;
  height: 1.15rem;
}

/* A web address used as its own link text has no spaces to break at, so a
   long one would push the card wider than the column on a narrow phone. */
.org__contact a {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Donation tiers ---------------------------------------------------------- */

/* Yes please / Maybe / No thanks on Donating Goods.

   One shape, three colours. A donor scanning this page should see three
   states of the same thing rather than three unrelated panels, so the tint,
   the padding and the radius are shared and only --tier carries the
   difference — which also means the icon, the edge and the markers can never
   drift out of agreement with each other. */
.tier {
  margin-block: calc(var(--space) * 1.5);
  padding: calc(var(--space) * 1.4) calc(var(--space) * 1.6);
  background: var(--color-surface);
  border-left: 5px solid var(--tier);
  border-radius: var(--radius);
}

.tier--yes { --tier: var(--color-tier-yes); }
.tier--maybe { --tier: var(--color-tier-maybe); }
.tier--no { --tier: var(--color-tier-no); }

.tier > :last-child {
  margin-bottom: 0;
}

/* The tier heading sits inside its own panel, so the section divider that
   .prose h2 draws above every other heading would split the panel from
   itself — the same exception the callout makes. */
.prose .tier h2 {
  margin-top: 0;
  margin-bottom: 0.9rem;
  padding-top: 0;
  border-top: 0;
}

.tier .h-icon {
  color: var(--tier);
}

/* Single-tone in the tier colour. Both custom properties are set, because the
   icon macro draws some parts with --icon-accent and a half-coloured tick
   would read as a rendering fault. The type selector beats
   `html.a11y-contrast .icon`, which flattens icons to dark ink and would
   erase the distinction between the three tiers exactly where it matters. */
.tier .icon,
html.a11y-contrast .tier .icon {
  --icon-stroke: var(--tier);
  --icon-accent: var(--tier);
}

/* The reason the Maybe tier exists, so it sits above its list rather than
   below it — a donor who reads the items first has already decided. */
.tier__note {
  margin: 0 0 1.1rem;
  font-weight: 600;
}

/* Two or three columns where there is room. The Maybe tier is eleven short
   entries and would otherwise run down the page far longer than the tier that
   matters most. Long entries simply wrap inside their column. */
.tier__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 0.75rem calc(var(--space) * 2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.tier__list li {
  position: relative;
  padding-left: 1.1rem;
  line-height: 1.55;
}

/* Yes please is six long sentences, not short items. In two columns each one
   wrapped into a tall ragged block and the rows ended at different heights;
   one per line they read as a list of sentences, with room between them. */
.tier--yes .tier__list {
  grid-template-columns: 1fr;
  gap: 1rem;
}

/* A plain dot, not a tick. The heading icon states which tier this is; a tick
   repeated beside every entry under "No thanks" would say the opposite. */
.tier__list li::before {
  content: "";
  position: absolute;
  left: 0.15rem;
  top: 0.62em;
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: var(--tier);
}

/* In-page links ----------------------------------------------------------- */

/* "On this page" links under a page title (Clothes). A wrapping row of
   bordered targets rather than a bulleted list: four short words read as a
   set of choices, and each one clears 44px so it is an easy tap on a phone. */
.prose .jump-links ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 calc(var(--space) * 1.5);
  padding: 0;
  list-style: none;
}

.prose .jump-links li {
  margin: 0;
}

.jump-links a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0.4rem 1rem;
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius);
  text-decoration: none;
}

.jump-links a:hover {
  text-decoration: underline;
}

/* FAQ accordion ----------------------------------------------------------- */

/* Native <details>/<summary>. Nothing here reimplements behaviour the element
   already has — no JS, no aria-expanded, no click handlers. The browser
   supplies the open/close state, the keyboard operation and the screen-reader
   announcement, and it keeps working if the stylesheet never loads.

   Rows sharing one border rather than three separate cards: these are one
   list of questions, and a stack of detached panels reads as several. */
.faq {
  margin-block: calc(var(--space) * 1.5);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius);
}

.faq__item + .faq__item {
  border-top: 1px solid var(--color-line-strong);
}

.faq__q {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  /* 44px on a single-line question, and it grows rather than clipping when one
     wraps to two. */
  min-height: 2.75rem;
  padding: 0.7rem 0.9rem;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  line-height: 1.35;
  color: var(--color-primary-deep);
  cursor: pointer;
  /* Removes the default disclosure triangle in both engines, so the chevron
     below is the only marker. `list-style` covers Firefox and Chrome;
     ::-webkit-details-marker is still needed for Safari. */
  list-style: none;
}

.faq__q::-webkit-details-marker {
  display: none;
}

/* Chevron, drawn from two borders so it needs no icon and no extra element.
   Order-swapped to sit at the end of the flex row, and pushed there by an auto
   margin so it stays put whether the question runs to one line or three. */
.faq__q::after {
  content: "";
  flex: none;
  order: 2;
  width: 0.55rem;
  height: 0.55rem;
  /* Optically centres the mark on the first line of the question rather than
     on the whole row — the same problem .h-icon solves, at a smaller scale. */
  margin: 0.42em 0 0 auto;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
}

.faq__item[open] .faq__q::after {
  transform: rotate(-135deg);
  /* Rotating about the box centre leaves the arrowhead sitting low once it
     points up, because the glyph's visual mass moves. */
  margin-top: 0.62em;
}

@media (prefers-reduced-motion: no-preference) {
  .faq__q::after {
    transition: transform 160ms ease;
  }
}

.faq__q:hover {
  background: var(--color-surface);
}

/* The row is the control, so the ring belongs around the row. Inset rather
   than the global 2px offset, which on a bordered row would draw the outline
   over the neighbouring row's border. */
.faq__q:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: -3px;
}

.faq__a {
  padding: 0 0.9rem 0.9rem;
}

.faq__a > :last-child {
  margin-bottom: 0;
}

/* People lists ------------------------------------------------------------ */

/* Staff and trustees on About Us. Columns rather than a single stack: fifteen
   names read as an organisation at a glance and as a queue in one column.

   Deliberately not the .card treatment. A bordered panel per person would
   promise a portrait and a biography, and there is neither yet for staff — a
   name in a box with nothing else in it looks like something failed to load.
   Trustees now have photographs; see .people--trustees below. */
.people {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.9rem var(--space);
  margin: 0 0 calc(var(--space) * 1.5);
  padding: 0;
  list-style: none;
}

.person__name {
  margin: 0;
  font-weight: 600;
}

.person__role {
  margin: 0;
  color: var(--color-muted);
}

/* Staff group photo. The source is a cut-out on pure white, which would sit
   as a pale box on the warm page. Multiply turns that white into whatever is
   behind it — the cream page, or white in contrast mode — without baking a
   colour into the file. The mask fades out the hard bottom edge where the
   photo cuts everyone off at the knees. */
.team-photo {
  display: block;
  width: 100%;
  height: auto;
  margin: 0 0 calc(var(--space) * 1.25);
  mix-blend-mode: multiply;
  -webkit-mask-image: linear-gradient(to bottom, #000 82%, transparent);
  mask-image: linear-gradient(to bottom, #000 82%, transparent);
}

/* The one role that is not yet known. Italic rather than a scaffold note: the
   person is confirmed and only their title is missing, so it is a gap in a
   real entry rather than a placeholder standing in for one. */
.person__role--pending {
  font-style: italic;
}

/* Trustees, with portraits. Each is a centred column of photo over name, so
   the grid reads as a row of faces. Circles at one size because the sources
   arrive in every shape (Timothy's is 111x125, the rest are 400px crops); a
   common frame is what makes them a set. The thin ring keeps a pale
   background — Josephine's and Robert's are near-white — from dissolving into
   the page. */
.people--trustees {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space);
}

/* Flex rather than the grid above so a short last row centres under the
   others instead of hanging off the left. 9.5rem fits four across the
   prose column (with the gaps) and two on a phone. */
.people--trustees > .person {
  flex: 0 0 9.5rem;
}

.person--portrait {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  text-align: center;
}

.person__photo {
  display: block;
  width: 7rem;
  height: 7rem;
  border-radius: 50%;
  object-fit: cover;
  background: var(--color-surface);
  box-shadow: 0 0 0 1px var(--color-line);
}

/* Stand-in for a trustee whose photo has not arrived. Initials in the same
   circle keep the grid even; aria-hidden because the name is right below. */
.person__photo--initials {
  display: grid;
  place-items: center;
  color: var(--color-muted);
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: 0.04em;
}

/* Vision and mission on About Us. The homepage sets these on a tinted band
   with a watermark; here they are two plain blocks on the page base, because
   this page has no hero above them to answer and the band would be the
   loudest thing on it. */
.tenets-inline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--space) calc(var(--space) * 1.5);
  margin-block: calc(var(--space) * 1.25);
}

.tenet-block__label {
  margin: 0 0 0.25rem;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-gold-deep);
}

.tenet-block p {
  margin: 0;
  font-size: var(--step-1);
}

/* Full width under the vision/mission pair, as on the homepage band. */
.tenet-block--values {
  grid-column: 1 / -1;
}

/* Scaffold notes ---------------------------------------------------------- */

/* TEMPORARY. Marks a page built before its content exists — see
   partials/scaffold-note.njk. Delete this block when the last scaffoldNote()
   call goes; nothing else uses these classes.

   Deliberately outside the design system's voice. Everything else on this site
   is a soft wash with a hairline or a solid rule; this is a dashed box with a
   monospace shout in it, because it has one job — to not be mistaken for the
   finished page. Contrast still has to hold, so the text sits on the base at
   the muted and body tokens rather than on a tint of its own. */
.scaffold-note {
  margin-block: calc(var(--space) * 1.5);
  padding: 1rem 1.25rem;
  border: 2px dashed var(--color-line-strong);
  border-radius: var(--radius);
  background: var(--color-surface);
}

.scaffold-note__label {
  margin: 0 0 0.35rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--color-gold-deep);
}

.scaffold-note__body {
  margin: 0;
  color: var(--color-muted);
}

/* Rhythm ------------------------------------------------------------------ */

/* Alternating tint bands break a long single-column page into readable
   stretches without touching the copy. */
.section--tint {
  background: var(--color-surface);
  border-block: 1px solid var(--color-line);
}

/* Pulls a key fact out of the flow. Not a blockquote — these are statements
   of fact, so it stays a <p> and gets weight from type and the gold rule. */
.pull-fact {
  margin-block: calc(var(--space) * 1.5);
  padding-left: var(--space);
  border-left: 3px solid var(--color-gold);
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.35;
  color: var(--color-primary-deep);
}

/* Media ------------------------------------------------------------------- */

.figure {
  margin: 0 0 var(--space);
}

.figure__img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
}

.figure__caption {
  margin-top: 0.5rem;
  font-size: 0.85rem;
  color: var(--color-muted);
}

/* Fixed-ratio frame so a swapped-in photo of any shape keeps the layout. */
.figure--crop .figure__img {
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

/* Portrait photos in a 3:2 frame: crop from near the top so faces stay in
   shot. The default centre crop cuts heads off. */
.figure--crop-top .figure__img {
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: 50% 20%;
}

.figure--square .figure__img {
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

/* Two photos side by side (homepage tea photos, Clothes racks). Stacks on
   narrow screens; the shared 3:2 frame keeps the pair level whatever shape
   the originals are. */
.photo-pair {
  display: grid;
  gap: var(--space);
  margin-block: var(--space);
}

@media (min-width: 36rem) {
  .photo-pair {
    grid-template-columns: 1fr 1fr;
  }
}

.photo-pair .figure {
  margin: 0;
}

/* Volunteer photos on Get Involved. A plain grid of 3:2 frames: eight
   photos of mixed orientation read as one set when they share a shape.
   Fixed steps rather than auto-fill, so eight photos always make full rows:
   one column on a phone, two on a tablet, four on desktop (auto-fill gave
   3+3+2 and left the last row short). */
.photo-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space);
  margin: calc(var(--space) * 1.5) 0 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 36rem) {
  .photo-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 60rem) {
  .photo-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.photo-grid .figure {
  margin: 0;
}

.pathway:hover .icon {
  --icon-stroke: var(--color-primary-deep);
}

/* Contrast mode flattens the two tones towards a single high-contrast ink —
   at that point legibility matters more than the two-tone treatment. */
html.a11y-contrast .icon {
  --icon-stroke: var(--color-text);
  --icon-accent: var(--color-primary);
}

/* "What we do" now introduces the column, so the pathways heading needs air
   above it to read as a new section rather than as a caption on that copy. */
.split__heading {
  margin-top: calc(var(--space) * 2);
}

.pathways {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--space);
  list-style: none;
  margin: 0;
  padding: 0;
}

.pathway {
  display: flex;
  flex-direction: column;
  padding: calc(var(--space) * 1.25);
  background: var(--color-bg);
  border: 1px solid var(--color-line);
  border-top: 3px solid var(--color-accent);
  border-radius: var(--radius);
}

.pathway__title {
  margin-bottom: 0.35em;
  font-size: var(--step-1);
}

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

/* Pushed to the bottom so links align across cards of differing height. */
.pathway__link {
  margin-top: auto;
  margin-bottom: 0;
  font-weight: 600;
}

.support {
  align-self: start;
  padding: calc(var(--space) * 1.5);
  background: var(--color-surface);
  border-top: 3px solid var(--color-warm);
  border-radius: var(--radius);
}

.support__heading {
  font-size: var(--step-1);
}

.support .button {
  width: 100%;
  text-align: center;
}

/* The three donor pathways. A stack rather than a row: the aside is the 1fr
   column, so three side-by-side tiles would each be too narrow to carry an
   icon and a label without wrapping the label. */
.ways {
  display: grid;
  gap: 0.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.way__link {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.55em 0.9em;
  border-radius: var(--radius);
}

/* Money keeps the gold button treatment — it is still the prominent route,
   just no longer the only visible one. The classes on the element are the
   existing `.button--warm`, so its hover and contrast-mode text colours come
   along unchanged; these rules only handle the icon beside the label. */
.way--primary .way__link {
  font-weight: 600;
}

/* The icon here is handled by the shared `.button .icon` rule — this link
   carries the .button classes, so it picks up currentColor with the rest. */

/* Goods and time read as links, not as two more buttons — equal weight to
   each other, one step below the primary. */
.way:not(.way--primary) .way__link {
  color: var(--color-accent);
  border: 1px solid var(--color-line-strong);
}

.way:not(.way--primary) .way__link:hover {
  border-color: var(--color-accent);
  background: var(--color-primary-soft);
}

.way .icon {
  width: 26px;
  height: 26px;
}

.support__meta {
  margin: var(--space) 0 0;
  padding-top: var(--space);
  border-top: 1px solid var(--color-line);
  font-size: 0.9rem;
  color: var(--color-muted);
}

.tenets {
  position: relative;
  overflow: hidden;
  padding-block: calc(var(--space) * 3);
  background: var(--color-surface);
  border-top: 1px solid var(--color-line);
}

.tenets__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: calc(var(--space) * 2);
}

.tenet__label {
  margin-bottom: 0.4em;
  font-size: 0.8rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-warm);
}

.tenet__text {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.45;
}

/* Full width below the vision/mission pair rather than a third column in the
   grid: at three tracks the two statements lose the width they need to read
   as statements, and five short values do not want a column of their own. */
.tenet--values {
  margin-top: calc(var(--space) * 2);
}

.values {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.9rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.45;
}

/* Same divider idiom as the nav row, in gold rather than blue so it ties to
   the labels in this band. Decorative and empty, so it is never announced —
   the values stay five list items to assistive tech. The dot rides inside the
   item with a matching gap, which keeps it centred between two values however
   the row wraps. */
.values li {
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

.values li:not(:last-child)::after {
  content: "";
  width: 0.3rem;
  height: 0.3rem;
  border-radius: 50%;
  background: var(--color-gold-deep);
}

.founder {
  margin: calc(var(--space) * 2) 0 0;
  font-size: 0.9rem;
  color: var(--color-muted);
}

@media (prefers-reduced-motion: no-preference) {
  .hero-home__eyebrow,
  .hero-home__strapline,
  .verse {
    animation: rise 600ms cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
  }

  .hero-home__strapline {
    animation-delay: 80ms;
  }

  .verse {
    animation-delay: 160ms;
  }

  .pathway {
    transition: transform 150ms ease, box-shadow 150ms ease;
  }

  .pathway:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(19, 48, 41, 0.1);
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--space);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Four cards as an even 2×2 (Get Help landing). The default auto-fit grid
   puts three on the first row and leaves the fourth alone on the second.
   One column on a phone, two from tablet width up. */
@media (min-width: 40rem) {
  .cards--pairs {
    grid-template-columns: repeat(2, 1fr);
  }
}

.card {
  padding: var(--space);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
}

.card__title {
  margin-top: 0;
}

/* Resets the browser's default 40px figure indent. */
.quote {
  margin: 0 0 calc(var(--space) * 1.5);
  padding-left: var(--space);
  border-left: 3px solid var(--color-accent);
}

.quote blockquote {
  margin: 0;
}

/* Portrait beside an attributed message. Floated rather than given a column of
   its own: these two messages run to a dozen lines each, and a fixed column
   would leave a tall empty gap under a 64px picture. Floated, the text closes
   around it and the quote stays one block of copy.

   Circular, and both at one size, because the two supplied files are 111x125
   and 100x138 — different shapes, neither square. A common crop is what makes
   the pair read as a set rather than as two photographs that happened to be to
   hand. Centre crop suits both: each face sits mid-frame, so nothing important
   is lost off the top or bottom.

   64px is the ceiling the source files can carry, not a design preference —
   see the note in the page template. Logical properties rather than left/right
   so this survives a future RTL pass without a second rule. */
.quote__portrait {
  float: inline-start;
  width: 4rem;
  height: 4rem;
  margin-block: 0.2rem 0.4rem;
  margin-inline: 0 0.9rem;
  border-radius: 50%;
  object-fit: cover;
}

.quote figcaption {
  color: var(--color-muted);
  font-size: 0.95rem;
}

/* CMS-authored body text. pre-line keeps any line breaks Karen types in the
   textarea, without needing a markdown pass. */
.cms-text {
  white-space: pre-line;
}

.list {
  padding-left: 1.2em;
}

.list li {
  margin-bottom: 0.6em;
}

/* Leaflet needs an explicit height on its container or it renders nothing. */
.map {
  height: 24rem;
  max-height: 70vh;
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
}

/* Pre-footer -------------------------------------------------------------- */

/* Base tone, not the footer's surface — a band the same colour as the footer
   is exactly what disappeared into it before. The gold edge is what marks
   this as a distinct panel, the same job it does on .callout, and it takes
   the deeper gold for the same reason: the bright step sits at 2.8:1 and a
   rule carrying meaning has to clear 3:1. */
.pre-footer {
  padding-block: calc(var(--space) * 1.5);
  background: var(--color-bg);
  border-top: 3px solid var(--color-gold-deep);
}

.pre-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem var(--space);
}

/* The door, matched to the direct child so the phone icon nested inside
   .pre-footer__phone keeps its own smaller size. Between the 32px wayfinding
   icons and the drop-in card's 3rem: this is a signpost, not the destination. */
.pre-footer__inner > .icon {
  width: 2.25rem;
  height: 2.25rem;
}

/* Takes the slack so the phone number is pushed to the far end on a wide
   screen, and wraps to its own line below 20rem rather than crushing. */
.pre-footer__text {
  flex: 1 1 20rem;
}

.pre-footer__title {
  margin: 0 0 0.1em;
  font-size: var(--step-1);
}

.pre-footer__line {
  margin: 0;
}

/* The one string here that must not be misread across a line break. */
.pre-footer__times {
  white-space: nowrap;
}

.pre-footer__phone {
  margin: 0;
  font-size: var(--step-1);
  font-weight: 600;
}

.pre-footer__phone a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.pre-footer__phone .icon {
  width: 22px;
  height: 22px;
}

/* Social ------------------------------------------------------------------ */

/* Every mark carries its name. The design brief's rule that icons supplement
   text and never replace it applies here as much as anywhere — a bare row of
   glyphs is precisely the case it guards against, and brand marks are no more
   readable to someone navigating in a second language than any other icon. */
.social {
  display: grid;
  gap: 0.45em;
  margin: 0;
  padding: 0;
  list-style: none;
}

.social a {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.social .icon {
  width: 20px;
  height: 20px;
}

/* A wrapping row for the contact page, where there is full column width to
   run along. The footer keeps the stack — its column is 15rem, and a row
   would break to two ragged lines. */
.social--row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem calc(var(--space) * 1.25);
}

.site-footer__social {
  margin-top: 0.9em;
}

/* Sponsors ---------------------------------------------------------------- */

/* No border-top and no top padding. Both were right when this strip was a
   sibling ABOVE the footer; once it moved inside the <footer> element they
   became duplicates of the footer's own rule and top padding, which is what
   produced the empty banded gap above "Supported by" — two hairlines 2rem
   apart with nothing between them. The footer now opens straight onto this. */
.sponsors {
  padding-block: 0 calc(var(--space) * 2);
}

.sponsors__heading {
  font-size: var(--step-0);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-muted);
}

.sponsors__list {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: var(--space);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* One identically sized tile per logo. The three files are very different
   shapes — roughly 2:1, 1.7:1 and square — so matching their heights alone
   still left the row looking arbitrary; a common frame is what actually
   evens it out. The white ground is deliberate and does not follow the
   theme: these logos are drawn for white, and it also means the National
   Lottery file (the only one supplied without transparency) stops showing as
   a pale rectangle against the warm base. Restrained frame, not a plaque. */
.sponsors__item {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 9.5rem;
  height: 4.5rem;
  padding: 0.6rem 0.9rem;
  background: #ffffff;
  /* --color-line would sit at 1.4:1 here and simply not read as a frame. The
     tiles are decorative — the logos identify themselves, so 3:1 is not
     required — but the frame has to be visible to do its job of evening the
     row, so this is a deliberate step darker. */
  border: 1px solid var(--color-line-frame);
  border-radius: var(--radius);
}

/* The three logos have very different aspect ratios — National Lottery is
   roughly 2:1, IJS 1.7:1, Salvation Army square. Capping height alone would
   let the wide ones dominate and leave the square one looking undersized, so
   both axes are bounded and the square logo gets a little more height to even
   out the optical weight. Subtle and consistent, not a partner banner. */
.sponsors__logo {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* A square mark reads smaller than a wide one boxed at the same height, so its
   tile is tightened to let it fill more of the frame. Driven by
   `"shape": "square"` in sponsors.json. Degrades to the standard padding
   where :has() is unsupported, which is merely a slightly smaller logo. */
.sponsors__item:has(.sponsors__logo--square) {
  padding: 0.3rem;
}

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

.site-footer {
  position: relative;
  overflow: hidden;
  background: var(--color-surface);
  border-top: 1px solid var(--color-line);
  padding-block: calc(var(--space) * 2) var(--space);
}

/* 12rem, not 15rem. The old minimum was set when this footer had two blocks;
   with four it lands exactly on the boundary at the 68rem wrap — 4 x 15rem
   plus three 2rem gaps is the content width to the pixel — so sub-pixel
   rounding was dropping the last block onto a row of its own. The tracks
   still resolve to ~15rem each once 1fr distributes the slack; the smaller
   minimum only buys the headroom to keep all four on one row. */
.site-footer__inner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: calc(var(--space) * 2);
}

.site-footer__heading {
  font-size: var(--step-0);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-muted);
}

.site-footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-footer__list li {
  margin-bottom: 0.4em;
}

/* Nested pages under their parent. The rule marks the nesting without
   indenting far enough to lose width — these sit in a 15rem column, and
   "Information for Current Volunteers" needs every character of it. */
.site-footer__sublist {
  list-style: none;
  margin: 0.4em 0 0;
  padding-left: 0.7rem;
  border-left: 1px solid var(--color-line);
  font-size: 0.95em;
}

.site-footer__sublist li {
  margin-bottom: 0.35em;
}

.site-footer__hours {
  margin-bottom: 0.6em;
  font-weight: 600;
}

.site-footer__address {
  margin-bottom: 0.6em;
  font-style: normal;
}

/* The one action in an otherwise reference-only block, so it takes the icon
   and a little weight — without becoming a button, which would set up a
   second call to action competing with the header's. */
.site-footer__phone {
  margin: 0;
  font-weight: 600;
}

.site-footer__phone a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.site-footer__phone .icon {
  width: 20px;
  height: 20px;
}

.site-footer__legal {
  margin-top: calc(var(--space) * 2);
  padding-top: var(--space);
  border-top: 1px solid var(--color-line);
  font-size: 0.9rem;
  color: var(--color-muted);
}

.site-footer__legal p {
  margin: 0;
}

/* A row on wide screens, a stack on narrow — as a list rather than one
   sentence of separator characters, so a wrap never orphans a divider on a
   line of its own. */
.site-footer__legal-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.8rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Same divider idiom as the nav and the values row, in the muted ink this
   line is set in. Decorative and empty, so it is never announced. */
.site-footer__legal-list li {
  display: flex;
  align-items: center;
  gap: 0.8rem;
}

.site-footer__legal-list li:not(:last-child)::after {
  content: "";
  width: 0.25rem;
  height: 0.25rem;
  border-radius: 50%;
  background: var(--color-muted);
}
