/* ============================================================================
   WAMcares — THE TABLE.  One stylesheet, deliberately.

   The previous direction split across system.css, home.css and pages.css and
   grew 47 components. The board's word for the result was "busy". This build
   holds the whole homepage in one file that a person can read start to finish,
   and the component count is the design constraint, not an accident.

   The governing device is the SEAM: a single hairline running down the left of
   the content column, the edge of a cloth laid on a table. Everything on the
   page registers to it. It is why the eye always knows where to land.
   ========================================================================= */

/* --------------------------------------------------------------- 1. RESET */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* The weave rides on each ground's own background, so it scrolls with the
   content and every ground carries it. */
body {
  background-image: var(--weave);
  background-color: var(--ground);
}

h1, h2, h3, p, figure, blockquote { margin: 0; }
img, svg, picture { display: block; max-width: 100%; }
img { height: auto; }

/* ------------------------------------------------- 2. BROWSER SURFACES */
/* The parts not drawn still belong to the design. */

::selection { background: var(--raw-wam-cyan); color: var(--raw-ink); }

:root { accent-color: var(--action); caret-color: var(--action); }

html {
  scrollbar-color: var(--raw-cloth-edge) var(--raw-cloth);
  scrollbar-width: thin;
}
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--raw-cloth-fold); }
::-webkit-scrollbar-thumb {
  background: var(--raw-cloth-edge);
  border: 3px solid var(--raw-cloth-fold);
}
::-webkit-scrollbar-thumb:hover { background: var(--seam-strong); }

:where(a, button, [tabindex]):focus-visible {
  outline: 3px solid var(--action);
  outline-offset: 3px;
  border-radius: 2px;
}
.field :where(a, button):focus-visible { outline-color: var(--raw-action-lift); }

a { color: inherit; text-underline-offset: 0.18em; text-decoration-thickness: 1px; }

.u-skip {
  position: absolute; left: -9999px;
  background: var(--action); color: var(--action-text);
  padding: var(--s-3) var(--s-5); z-index: 99;
}
.u-skip:focus { left: var(--s-4); top: var(--s-4); }

.u-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ----------------------------------------------------- 3. SHELL AND SEAM */

.shell {
  width: min(100% - var(--shell-pad) * 2, var(--shell));
  margin-inline: auto;
}

/* The seam. One hairline running the full height of a region with every
   element inside indented from it, so it reads as the edge of a cloth laid
   on the table rather than as a stray rule. Drawn on the region, so it
   breaks between grounds instead of running behind them.

   It sits at the content's own left edge and the content steps in from it.
   An earlier version placed it out in the shell's outer margin, where it
   governed nothing and was invisible besides. */
.seamed { position: relative; padding-left: var(--s-6); }
@media (min-width: 760px) { .seamed { padding-left: var(--s-7); } }
.seamed::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--seam-strong);
}
@media (max-width: 560px) {
  .seamed { padding-left: var(--s-4); }
  .seamed::before { width: 1px; }
}

/* ---------------------------------------------------------- 4. TYPE ROLES */

.d1, .d2, .d3 { font-family: var(--font-display); font-weight: 700; }
.d1 { font-size: var(--fs-d1); line-height: var(--lh-d1); letter-spacing: var(--tr-d1); text-wrap: balance; }
.d2 { font-size: var(--fs-d2); line-height: var(--lh-d2); letter-spacing: var(--tr-d2); text-wrap: balance; }
.d3 { font-size: var(--fs-d3); line-height: var(--lh-d3); letter-spacing: var(--tr-d3); font-weight: 600; }

.lead {
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  max-width: var(--measure-narrow);
  color: var(--text-soft);
}

.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--s-4); }
.prose strong { font-weight: 600; }

.note {
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--text-soft);
}
/* A qualification the reader needs is prose, not a caption. Body size, body
   measure, secondary colour: PRODUCT.md floors body copy at 16px. */
.qual {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-soft);
  max-width: var(--measure);
}

/* A pending fact is a quiet italic note in the running text, not a hatched
   box. Twelve hatched boxes on the previous homepage were read as clutter,
   and a placeholder that shouts is worse than one that simply reads. */
.pending {
  font-style: italic;
  color: var(--text-soft);
  border-bottom: 1px dashed var(--seam);
  padding-bottom: 1px;
}
.field .pending { color: var(--text-on-field-soft); border-bottom-color: var(--seam-field); }

/* ------------------------------------------------------------ 5. CONTROLS */

.act {
  display: inline-flex; align-items: center; gap: var(--s-3);
  padding: 0.85em 1.6em;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 600;
  text-decoration: none;
  border: 0;
  cursor: pointer;
  background: var(--action);
  color: var(--action-text);
  transform: translateY(var(--press, 0px));
  box-shadow: var(--lift);
  transition: background 180ms var(--ease-out), box-shadow 180ms var(--ease-out);
}
.act:hover { background: var(--action-hover); }
.field .act { box-shadow: inset 0 0 0 1px rgba(251, 247, 240, 0.62), var(--lift); }
.field .act:active { box-shadow: inset 0 0 0 1px rgba(251, 247, 240, 0.62); }
.act:active { --press: 1px; box-shadow: 0 1px 2px -1px rgba(42,32,24,0.22); }

/* The quiet action. A ruled link, never a second filled button competing
   with the primary. */
.act-quiet {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: 0.85em 0;
  font-weight: 500;
  color: var(--text-accent);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  transition: color 160ms var(--ease-out);
}
.act-quiet:hover { color: var(--raw-ink); }
.field .act-quiet { color: var(--text-on-field-accent); }
.field .act-quiet:hover { color: var(--raw-light); }

.acts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-6); }

/* -------------------------------------------------------------- 6. HEADER */

.head {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--raw-cloth) 88%, transparent);
  backdrop-filter: blur(14px) saturate(150%);
  border-bottom: 1px solid var(--seam);
}
@media (prefers-reduced-transparency: reduce) {
  .head { background: var(--raw-cloth); backdrop-filter: none; }
}
@media (prefers-contrast: more) {
  .head { background: var(--raw-cloth); backdrop-filter: none; }
}

.head__bar {
  display: flex; align-items: center; gap: var(--s-6);
  padding-block: var(--s-4);
}
.head__mark { flex: 0 0 auto; display: inline-flex; }
.head__mark img { width: clamp(124px, 15vw, 178px); }

.nav { display: none; margin-left: auto; }
@media (min-width: 900px) { .nav { display: flex; align-items: center; gap: var(--s-5); } }
.nav a {
  white-space: nowrap;
  font-size: var(--fs-small);
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
  padding-block: var(--s-2);
  border-bottom: 2px solid transparent;
  transition: border-color 160ms var(--ease-out);
}
.nav a:hover, .nav a[aria-current="page"] { border-bottom-color: var(--action); }

.head__end { margin-left: auto; display: flex; align-items: center; gap: var(--s-4); }
@media (min-width: 900px) { .head__end { margin-left: 0; } }

.menu {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  background: none; border: 1px solid var(--seam); cursor: pointer;
  color: var(--text);
}
@media (min-width: 900px) { .menu { display: none; } }
.menu svg { width: 20px; height: 20px; }

.sheet {
  display: none;
  padding: var(--s-5) 0 var(--s-7);
  border-bottom: 1px solid var(--seam);
  background: var(--raw-cloth);
}
.sheet[data-open="true"] { display: block; }
@media (min-width: 900px) { .sheet { display: none !important; } }
.sheet a {
  display: block; padding: var(--s-3) 0;
  font-size: var(--fs-lead);
  font-family: var(--font-display);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid var(--seam);
}

/* --------------------------------------------------------------- 7. BANDS */

.band { padding-block: var(--band-pad); }
.band--fold { background-color: var(--ground-fold); background-image: var(--weave); }

.field { color: var(--text-on-field); }
.field .d1, .field .d2, .field .d3 { color: var(--text-on-field); }
.field .lead, .field .note, .field .qual { color: var(--text-on-field-soft); }
.field--blue   { background-color: var(--field-blue);   background-image: var(--weave-field); }
.field--indigo { background-color: var(--field-indigo); background-image: var(--weave-field); }
.field .seamed::before { background: var(--seam-field); }
.field--indigo .seamed::before { background: var(--seam-indigo); }

/* More space above a heading than below it, everywhere. */
.band__head { margin-bottom: var(--s-7); }
.band__head .d2 + .lead { margin-top: var(--s-4); }

/* ------------------------------------------------- 7b. INTERIOR PAGE HEAD */
/* Interior pages open with the same plate the homepage uses, then a display
   title. The homepage ranks scripture above its name; an interior page ranks
   its own subject, so the title takes the display step there. */

.pagehead__grid { display: grid; gap: var(--s-7); }
@media (min-width: 900px) {
  .pagehead__grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); gap: var(--s-9); align-items: end; }
}
.pagehead__title { margin-bottom: var(--s-5); }
.crumb {
  font-size: var(--fs-small);
  color: var(--text-soft);
  margin-bottom: var(--s-4);
}
.crumb a { color: var(--text-accent); text-decoration: none; border-bottom: 1px solid currentColor; }
.crumb span { padding-inline: var(--s-2); }

/* A document with a state. Same row grammar as the works list, so the site
   has one list, not two that merely resemble each other. */
.doclist { border-top: 1px solid var(--seam); }
.docrow {
  display: grid; gap: var(--s-2) var(--s-6);
  padding-block: var(--s-5);
  border-bottom: 1px solid var(--seam);
  align-items: baseline;
}
@media (min-width: 700px) { .docrow { grid-template-columns: minmax(0, 1fr) 14rem; } }
.docrow__name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-d3); }
.docrow__note { color: var(--text-soft); font-size: var(--fs-small); margin-top: var(--s-1); }
.docrow__state { font-size: var(--fs-small); font-weight: 600; }
@media (min-width: 700px) { .docrow__state { text-align: right; } }
.docrow__state--on { color: var(--text-accent); }

/* The field note index. A dated list, not a card wall. */
.notes { border-top: 1px solid var(--seam); }
.noteitem {
  display: grid; gap: var(--s-1) var(--s-6);
  padding-block: var(--s-4);
  border-bottom: 1px solid var(--seam);
  text-decoration: none; color: inherit;
  transition: background 180ms var(--ease-out);
}
@media (min-width: 700px) { .noteitem { grid-template-columns: 1fr 11rem; align-items: baseline; } }
.noteitem > * { transition: transform 220ms var(--ease-out); }
.noteitem:hover, .noteitem:focus-visible { background: var(--ground-fold); }
.noteitem:hover > *, .noteitem:focus-visible > * { transform: translateX(8px); }
.noteitem__title { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-d3); line-height: 1.3; }
.noteitem:hover .noteitem__title { color: var(--text-accent); }
.noteitem__meta { font-size: var(--fs-small); color: var(--text-soft); }
@media (min-width: 700px) { .noteitem__meta { text-align: right; } }

/* An empty state that is composed rather than apologetic. */
.empty {
  border: 2px solid var(--seam);
  padding: var(--s-8) var(--s-6);
  text-align: center;
}
.empty .d3 { margin-bottom: var(--s-3); }
.empty p { max-width: 44ch; margin-inline: auto; color: var(--text-soft); }
.empty .acts { justify-content: center; margin-top: var(--s-6); }

/* ------------------------------------------------------------ 8. OPENING */

.open__grid {
  display: grid;
  gap: var(--s-8);
  align-items: center;
}
/* On one column the photograph crops to a portrait-leaning frame rather than
   falling back to the source's 2.14:1, which renders a 167px strip on a
   phone. object-position keeps the four figures, not the parked cars.
   It also moves ahead of the actions and the verse, so the first screen on a
   phone carries the image rather than closing on a pending slot. */
@media (max-width: 959px) {
  .open__grid { display: flex; flex-direction: column; gap: var(--s-4); }
  .open__grid > div { display: contents; }
  /* 2026-09-02. The reshaped opening is two blocks, not a flat list of
     elements, so the phone stacks the blocks and lets each keep its own
     internal order. `display: contents` is confined to the say block. */
  .open__grid > .open__say { display: contents; }
  .masthead      { order: 1; margin-bottom: var(--s-5); }
  .open__tagline { order: 2; }
  .open__lead    { order: 3; margin-top: var(--s-5); }
  .open__acts    { order: 4; margin-top: var(--s-6); }
  .open__aside   { order: 5; margin-top: var(--s-7); }
  .open__verse   { margin-top: 0; }
}
@media (max-width: 959px) {
  .open__grid .photo img,
  .who__grid .photo img {
    aspect-ratio: 4 / 3;
    object-fit: cover;
    object-position: 42% 50%;
    width: 100%;
  }
}

@media (min-width: 960px) {
  .open__grid {
    grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.94fr);
    gap: var(--s-8);
    align-items: stretch;
  }
  /* The photograph matches the text column's height and crops to fill, so
     the opening reads as one block rather than as text beside a strip. */
  .open__grid .photo { display: flex; flex-direction: column; }
  /* Capped so the verse, the offer and the action clear one screen at
     1440x900: an opening that needs a scroll to reach its own button has
     not opened. */
  .open__grid .photo picture { flex: 1 1 auto; min-height: 24rem; max-height: 34rem; display: block; }
  .gallery .photo picture { display: block; }
  .open__grid .photo img { height: 100%; object-fit: cover; object-position: 50% 46%; }
}

/* The masthead. The organisation's name reads as the plate at the head of a
   ministry publication: present, ranked, and deliberately smaller than the
   verse beneath it, because on this page scripture is the voice and the name
   is the signature. It remains the document's h1. */
.masthead {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-accent);
  padding-bottom: var(--s-4);
  margin-bottom: var(--s-6);
  border-bottom: 2px solid var(--seam-strong);
  max-width: 24rem;
}

.open__title { margin-bottom: var(--s-5); }
.open__lead { max-width: 46ch; margin-top: var(--s-6); }
.open__lead strong { color: var(--text); font-weight: 600; }
.open__acts { margin-top: var(--s-7); }

/* Scripture. A brand commitment, and in this direction it is the page's
   opening voice rather than a thin ruled band two thirds of the way down. */
.verse {
  margin-top: var(--s-8);
  padding-top: var(--s-5);
  border-top: 1px solid var(--seam);
  max-width: 40ch;
}
.verse p {
  font-family: var(--font-display);
  font-size: var(--fs-d3);
  line-height: 1.35;
  font-style: italic;
  font-weight: 500;
}

/* In the opening the verse is not a pull quote under the fold, it is the
   page's first and largest voice. Tracking tightens as the size rises. */
.verse--lead {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
  max-width: 26ch;
}
.verse--lead p {
  font-size: var(--fs-voice);
  line-height: 1.12;
  letter-spacing: -0.016em;
  font-weight: 500;
  text-wrap: balance;
}
.verse--lead cite {
  margin-top: var(--s-3);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.verse cite {
  display: block;
  margin-top: var(--s-3);
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-style: normal;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-accent);
}

/* A photograph is a photograph. No frame, no registration marks, no badge
   plate: the release note reads underneath as a line of text. */
.photo { }
.photo img { width: 100%; box-shadow: var(--lift-photo); }
.photo figcaption { margin-top: var(--s-3); }

/* ------------------------------------------------- 9. THE CAMPAIGN BAND */
/* The one dense region on an otherwise open page. Everything else breathes
   so that this can be crowded and still read as deliberate. */

.one__grid { display: grid; gap: var(--s-8); }
@media (min-width: 900px) {
  .one__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr); gap: var(--s-9); align-items: start; }
}

.one__equation {
  font-family: var(--font-display);
  font-size: var(--fs-equation);
  line-height: 1.3;
  font-weight: 600;
  margin-top: var(--s-5);
}
.one__equation span { display: block; }
.one__equation span + span { margin-top: var(--s-1); }
.one__equation b { font-weight: 700; color: var(--text-on-field-accent); font-style: italic; }

/* Twelve months. A gift stamps one. They stamp in sequence when the band
   arrives, each landing before the next is dealt; the page's one authored
   motion. A stamped month is the cloth showing through the field, which is a
   value change rather than a second action colour. */
.months {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2px;
  background: var(--seam-field);
  border: 1px solid var(--seam-field);
  max-width: 30rem;
}
/* Four across, three down. The six-wide arrangement made a short wide strip
   that left the ask band's right column mostly empty and read as a bar rather
   than as a year. Three rows of four is calendar-shaped and balances the
   column beside it. */
.month {
  aspect-ratio: 1 / 1;
  display: grid; place-items: center;
  background: var(--field-blue);
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--text-on-field-soft);
  /* 130ms, so each stamp lands before the next is dealt. At 240ms against a
     90-170ms interval three tiles were cross-fading at once and none landed. */
  transition: background 130ms var(--ease-out), color 130ms var(--ease-out);
}
.month[data-filled="true"] {
  background: var(--stamp);
  color: var(--stamp-text);
}

.months__note { margin-top: var(--s-4); max-width: 30rem; }

/* --------------------------------------------------- 9b. THE CONVICTION */
/* One sentence, alone on a field. A dense band earns a bare one, and this is
   the bare one: the page's quiet passage between the programs and the record. */

.conviction { padding-block: clamp(4rem, 8vw, 8rem); }
.conviction__line {
  font-family: var(--font-display);
  font-size: var(--fs-voice-sm);
  line-height: 1.16;
  letter-spacing: -0.015em;
  font-weight: 600;
  font-style: italic;
  /* The line lives on cloth now that it closes the tension beat; it keeps the
     on-field value for any band that still sets it over a field. */
  color: var(--text-accent);
  max-width: 24ch;
  text-wrap: balance;
}
.field .conviction__line { color: var(--text-on-field); }

/* --------------------------------------------------------- 9c. THE PILLARS */
/* Four ministry priorities, each holding the programs that already exist.
   Not four equal cards: the pillar is a heading with its work listed beneath
   it, so the framework reads as an organising idea rather than as a menu.
   Diane's architecture; the names carry Kathy's register. */

.pillars { display: grid; gap: var(--s-8); }
@media (min-width: 860px) { .pillars { grid-template-columns: 1fr 1fr; gap: var(--s-9) var(--s-8); } }

.pillar { border-top: 2px solid var(--seam-strong); padding-top: var(--s-5); }
.pillar__name {
  font-family: var(--font-display);
  font-size: var(--fs-d3);
  font-weight: 700;
  line-height: 1.2;
  margin-bottom: var(--s-3);
}
.pillar__why { color: var(--text-soft); max-width: 46ch; margin-bottom: var(--s-5); }
.pillar__list { list-style: none; margin: 0; padding: 0; }
.pillar__list li + li { margin-top: var(--s-1); border-top: 1px solid var(--seam); }
.pillar__list a,
.pillar__list span {
  display: block;
  padding-block: var(--s-3);
  text-decoration: none;
  font-weight: 500;
  transition: color 160ms var(--ease-out), transform 200ms var(--ease-out);
}
.pillar__list a:hover, .pillar__list a:focus-visible {
  color: var(--text-accent);
  transform: translateX(6px);
}
.field .pillar { border-top-color: var(--seam-field); }
.field .pillar__why { color: var(--text-on-field-soft); }
.field .pillar__list li + li { border-top-color: var(--seam-field); }
.field .pillar__list a:hover { color: var(--text-on-field-accent); }

/* The step the visitor is on. Diane's journey is five moves, and each band
   says which one it is without numbering itself: numbers would read as a
   directory again, which is the thing the framework replaces. */
.step { margin-bottom: var(--s-3); }

/* ---------------------------------------------------- 10. WHAT WE DO LIST */
/* A list, not a grid of same-size cards. No numbers: the order carries no
   information, so numbering it would be decoration pretending to be data. */

.works { border-top: 1px solid var(--seam); }
.work {
  display: grid;
  gap: var(--s-2) var(--s-6);
  padding-block: var(--s-5);
  border-bottom: 1px solid var(--seam);
  text-decoration: none;
  color: inherit;
  /* The row steps in on hover. The step is a transform on the contents, not
     an animated padding: animating a layout property thrashes layout on a
     seven-row list and janks on a phone. */
  transition: background 180ms var(--ease-out);
}
.work > * { transition: transform 220ms var(--ease-out); }
.work:hover > *, .work:focus-visible > * { transform: translateX(8px); }
@media (min-width: 760px) {
  .work { grid-template-columns: 15rem minmax(0, 1fr); align-items: baseline; }
}
.work:hover, .work:focus-visible { background: var(--ground-fold); }
.work__name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-d3); }
.work:hover .work__name { color: var(--text-accent); }
.work__body { color: var(--text-soft); max-width: var(--measure); }

/* ------------------------------------------------- 10b. THE WORK, SEEN */
/* Two frames side by side and nothing to read. The page spends most of its
   length making a case; this is where it stops and lets the work be looked
   at. Captions carry the release state, which is the only text here. */

.gallery { display: grid; gap: var(--s-6); }
@media (min-width: 820px) {
  .gallery { grid-template-columns: 1.15fr 1fr; gap: var(--s-7); align-items: end; }
  /* Unequal columns and a shared baseline: two identical frames side by side
     is the contact sheet, not a composition. */
  .gallery .photo:first-child img { aspect-ratio: 4 / 3;  object-fit: cover; width: 100%; }
  .gallery .photo:last-child  img { aspect-ratio: 1 / 1;  object-fit: cover; width: 100%; }
}

/* ---------------------------------------------------------- 11. WHO WE ARE */

.who__grid { display: grid; gap: var(--s-8); }
@media (min-width: 960px) {
  .who__grid {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    gap: var(--s-9);
    align-items: stretch;
  }
  .who__grid .photo { display: flex; flex-direction: column; justify-content: center; }
  /* A <picture> is an inline wrapper with no height of its own, so height:100%
     on the img inside it resolves against nothing and the frame collapses.
     The wrapper has to carry the height before the image can fill it. */
  .who__grid .photo picture { display: block; flex: 1 1 auto; min-height: 20rem; max-height: 32rem; }
  .who__grid .photo img { height: 100%; object-fit: cover; }
}

/* ----------------------------------------------------------- 12. FIGURES */
/* Small, quiet, in one row. These are supporting evidence on a ministry
   page, not the page's argument. */

.figures {
  display: grid; gap: var(--s-6);
  border-top: 1px solid var(--seam);
  padding-top: var(--s-6);
}
@media (min-width: 700px) { .figures { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .figures { grid-template-columns: repeat(4, 1fr); } }

.fig__n {
  font-family: var(--font-display);
  font-size: var(--fs-figure);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums lining-nums;
}
.fig__what { margin-top: var(--s-2); max-width: 24ch; }
/* A figure that does not exist yet is set as a note, not as a number. */
.fig__n .pending {
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: 0;
}
.fig__src {
  margin-top: var(--s-3);
  font-size: var(--fs-small);
  color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------------------- 13. GIVE */

.give__grid { display: grid; gap: var(--s-7); }
@media (min-width: 860px) { .give__grid { grid-template-columns: repeat(3, 1fr); gap: var(--s-8); } }
.give__way { display: flex; flex-direction: column; gap: var(--s-3); align-items: flex-start; }
.give__way .act, .give__way .act-quiet { margin-top: auto; }

/* The ranked ask. Three unequal actions were drawn as three equal boxes, which
   lets a visitor choose the cheapest one and leave feeling complete. Give is
   now the widest column, carries the display step above its siblings, and is
   the only one whose top rule is in the accent. Pray and Partner keep their
   place; they lose their claim to equal weight. */
.give__grid--ranked .give__way {
  border-top: 2px solid var(--seam-indigo);
  padding-top: var(--s-5);
}
.give__grid--ranked .give__way--lead { border-top-color: var(--text-on-field-accent); }
.give__way--lead .d3 { font-size: var(--fs-d2); line-height: var(--lh-d2); }
@media (min-width: 860px) {
  .give__grid--ranked { grid-template-columns: 1.35fr 1fr 1fr; align-items: start; }
}

/* Stewardship, inside the ask. A donor decides on transparency at the moment
   of giving, not on a page they reach afterwards, so the accountability record,
   the Candid profile and the exemption line sit in the band that asks. */
.trust {
  margin-top: var(--s-8);
  padding-top: var(--s-5);
  border-top: 1px solid var(--seam-indigo);
}
.trust__links { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-6); }
.trust__links a { color: var(--text-on-field-accent); }
.trust__legal { margin-top: var(--s-3); max-width: 68ch; }

/* Protection, closing the page rather than interrupting it at position three. */
.protect {
  margin-top: var(--s-9);
  padding-top: var(--s-6);
  border-top: 1px solid var(--seam-indigo);
}
.give__legal {
  margin-top: var(--s-8); padding-top: var(--s-5);
  border-top: 1px solid var(--seam-indigo);
  max-width: 62ch;
}

/* ------------------------------------------------------------ 14. FOOTER */

.foot {
  background-color: var(--field-indigo);
  background-image: var(--weave-field);
  color: var(--text-on-field);
  padding-block: var(--s-8) var(--s-7);
}
.foot a { color: var(--text-on-field); text-decoration: none; }
.foot .note, .foot .qual { color: var(--text-on-field-soft); }
.foot .act-quiet { color: var(--text-on-field-accent); }
.foot a:hover { text-decoration: underline; }

.foot__top { display: grid; gap: var(--s-7); }
@media (min-width: 760px) { .foot__top { grid-template-columns: 1.3fr 1fr 1fr; gap: var(--s-8); } }
.foot__mark img { width: 178px; margin-bottom: var(--s-5); }
.foot address { font-style: normal; color: var(--text-on-field-soft); }
.foot h2 {
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-on-field-accent);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--seam-indigo);
  margin-bottom: var(--s-4);
}
.foot ul { list-style: none; margin: 0; padding: 0; }
.foot li + li { margin-top: var(--s-3); }

/* The cross-track handoff sits as a peer of the footer links it follows, in
   the body face at body-adjacent size, under a hairline. It must not read as
   a heading and must not out-mass its column. */
.crosstrack {
  margin-top: var(--s-6); padding-top: var(--s-4);
  border-top: 1px solid var(--seam-indigo);
}
.crosstrack__name { font-weight: 600; margin-bottom: var(--s-2); }
.crosstrack .note + .note { margin-top: var(--s-3); }
.foot .pending { color: var(--text-on-field-soft); border-bottom-color: var(--seam-indigo); }

.social { display: flex; gap: var(--s-3); margin-top: var(--s-5); }
.social a {
  display: grid; place-items: center; width: 40px; height: 40px;
  border: 1px solid var(--seam-indigo);
}
.social a:hover { border-color: var(--action); }
.social svg { width: 17px; height: 17px; fill: currentColor; }

.foot__end {
  margin-top: var(--s-8); padding-top: var(--s-5);
  border-top: 1px solid var(--seam-indigo);
  display: grid; gap: var(--s-4);
  color: var(--text-on-field-soft);
  font-size: var(--fs-small);
}
@media (min-width: 760px) { .foot__end { grid-template-columns: 1fr auto; align-items: end; } }

/* ------------------------------------------------- 15. REVEAL, ONE MOMENT */
/* Content is visible by default. JavaScript opts elements in only when it is
   running and motion is allowed, so nothing depends on script to be read. */

[data-rise] { opacity: 1; }
html.js [data-rise] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 620ms var(--ease-out), transform 620ms var(--ease-out);
  transition-delay: var(--rise-delay, 0ms);
}
html.js [data-rise][data-shown="true"] { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html.js [data-rise] { opacity: 1; transform: none; transition: none; }
}

/* ==========================================================================
   HELMI CO ADDITIONS — 2026-09-02, umbrella direction.

   Three things the September feedback asked for and this build did not have:
   a full-bleed hero triptych, three paths to the three operating names, and a
   Wamhiba feature. Plus two hygiene fixes found in the audit of the live
   previews. Everything below uses Layer 2 roles only; no hex literals.
   ========================================================================== */

/* -- Hygiene 1: the sticky header was clipping every section heading a nav
   -- link or an in-page anchor landed on. ---------------------------------- */
.band { scroll-margin-top: 6rem; }

/* -- Hygiene 2: [data-rise] left headings near-invisible until an observer
   -- fired. A fast scroller, a slow device or a failed observer saw ghost
   -- text. The reveal is now inert: content is visible on arrival. ---------- */
html.js [data-rise] { opacity: 1 !important; transform: none !important; transition: none !important; }

/* -- The triptych ---------------------------------------------------------
   Full bleed, three panels, one indigo ground and one woven tooth beneath
   them so the set reads as a single cloth rather than three cards. The
   headline is not laid over a face: it lives in the band underneath. ------ */
.tri {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  background-color: var(--field-indigo);
  background-image: var(--weave);
}
.tri__panel { position: relative; min-height: clamp(19rem, 43vw, 31rem); overflow: hidden; }
.tri__panel img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tri__panel::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top,
    rgba(12, 39, 66, 0.88) 0%, rgba(12, 39, 66, 0.24) 46%, rgba(12, 39, 66, 0) 72%);
}
.tri__cap {
  position: absolute; z-index: 2; left: 0; right: 0; bottom: 0;
  margin: 0 clamp(1rem, 2vw, 1.9rem);
  padding: clamp(1rem, 2vw, 1.9rem) 0 clamp(1rem, 2vw, 1.9rem) var(--s-4);
  border-left: 2px solid var(--seam-strong);
  color: var(--text-on-field);
  text-shadow: 0 1px 14px rgba(12, 39, 66, 0.62);
}
.tri__name {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.15rem, 1rem + 0.6vw, 1.55rem);
  letter-spacing: -0.012em; line-height: 1.18; margin: 0 0 0.12em;
}
.tri__line { font-size: var(--fs-small); color: var(--raw-light-soft); margin: 0; }
.tri__note { font-size: 0.75rem; font-style: italic; color: var(--raw-light-soft); margin: 0.4rem 0 0; }
@media (max-width: 53.99rem) {
  /* Three panels at 400px would be three 133px strips. On a phone the lead
     photograph carries the hero and the three path cards carry the triad. */
  .tri { grid-template-columns: 1fr; }
  .tri__panel { min-height: min(46vh, 22rem); }
  .tri__panel[data-mobile="hide"] { display: none; }
}

/* -- The three paths ------------------------------------------------------ */
.paths { display: grid; gap: var(--s-7); margin-top: var(--s-8); }
@media (min-width: 54rem) { .paths { grid-template-columns: repeat(3, 1fr); gap: var(--s-8); } }
.path { display: flex; flex-direction: column; }
.path__plate {
  position: relative; aspect-ratio: 5 / 3; overflow: hidden;
  background-color: var(--field-indigo); background-image: var(--weave);
  box-shadow: var(--lift-photo); margin-bottom: var(--s-4);
}
.path__plate img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.path__kind {
  display: block; font-family: var(--font-body);
  font-size: 0.8125rem; font-weight: 700; letter-spacing: 0.015em;
  color: var(--text-accent); margin-bottom: 0.25rem;
}
.field .path__kind { color: var(--text-on-field-accent); }
.path__name { margin: 0 0 0.3em; }
.path p { color: var(--text-soft); margin-bottom: 0; }
.path__go { margin-top: auto; padding-top: var(--s-4); }

/* -- The entity disclosure. Required on the hub and on all three path pages,
   -- because three names on one page must not imply three organisations. --- */
.entity {
  margin-top: var(--s-5); padding-top: var(--s-4);
  border-top: 1px solid var(--seam); max-width: 56ch;
}
.field .entity { border-top-color: var(--seam-field); }

/* -- Wamhiba feature band ------------------------------------------------- */
.grow__grid { display: grid; gap: var(--s-6); }
@media (min-width: 60rem) {
  .grow__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-8); align-items: center; }
}
.grow__list { display: grid; gap: var(--s-5); margin-top: var(--s-6); }
@media (min-width: 40rem) { .grow__list { grid-template-columns: repeat(3, 1fr); } }
.grow__item { border-top: 2px solid var(--seam-strong); padding-top: var(--s-4); }
.field .grow__item { border-top-color: var(--seam-field); }
.grow__item p { margin: 0.35rem 0 0; }

/* -- Forms. The build had none; Adopt-a-Church needs one because the packet is
   -- requested rather than published. Netlify Forms handles the submission. -- */
.form { display: grid; gap: var(--s-5); max-width: 34rem; }
.field-row { display: grid; gap: var(--s-2); margin: 0; }
.field-row label { font-weight: 700; font-size: var(--fs-small); }
.field-row input,
.field-row textarea {
  font-family: var(--font-body); font-size: 1rem; color: var(--text);
  background: var(--raw-light);
  border: 1px solid var(--seam);
  border-radius: 2px;
  padding: 0.7rem 0.85rem;
  min-height: 2.875rem;
}
.field-row textarea { resize: vertical; }
.field-row input:focus-visible,
.field-row textarea:focus-visible { border-color: var(--action); }
.form .acts { margin-top: var(--s-2); }
.form button.act { font-family: var(--font-body); border: 0; cursor: pointer; }

/* -- .works was only ever used on the cloth ground, so its colours are cloth
   -- colours. /relief/ puts a registrations list on the blue field, where
   -- --text-soft measured 1.42:1. Give the list a field variant. ----------- */
.field .works { border-top-color: var(--seam-field); }
.field .work { border-bottom-color: var(--seam-field); }
.field .work__name { color: var(--text-on-field); }
.field .work__body { color: var(--text-on-field-soft); }
.field a.work:hover .work__name { color: var(--text-on-field-accent); }


/* -- The opening, reshaped 2026-09-02 -------------------------------------
   The tagline replaced the scripture as the page's first voice, which left
   the right column empty above the fold and put the verse between the promise
   and the button. Two blocks now: what WAM says on the left, ending on the
   action with nothing in the way of it, and the voice and the legal identity
   on the right, top-aligned so the two columns start on the same line. ---- */
.open__say { display: flex; flex-direction: column; align-items: flex-start; }

/* The eyebrow rule is a signature, so it measures the name rather than
   reaching for an arbitrary 24rem. */
.open__say .masthead { max-width: max-content; padding-right: var(--s-7); }

/* Three words. Balanced, held to a measure that breaks them two-and-one on
   purpose rather than orphaning "crisis" at whatever width the viewport is. */
.open__tagline { max-width: 13ch; margin-bottom: 0; text-wrap: balance; }

.open__lead { max-width: 44ch; }

/* The actions are the end of the left column, and nothing follows them. */
.open__acts { margin-top: var(--s-7); }

@media (min-width: 960px) {
  /* Top-aligned, not centred: the eyebrow and the verse should begin on the
     same optical line so the two columns read as one block. */
  .open__grid { align-items: start; }
  .open__aside { padding-top: var(--s-2); }
  /* The verse carries its own rule already; a second one above it inside the
     aside would double the line. */
  .open__verse { margin-top: 0; padding-top: 0; border-top: 0; max-width: 26ch; }
  .open__entity { margin-top: var(--s-8); }
}
.open__verse p { max-width: 26ch; }

/* -- Opening, corrections 2026-09-02 -------------------------------------- */

@media (max-width: 959px) {
  /* .open__grid carries align-items: center from its base rule. The mobile
     block redeclares display and direction but not alignment, so every item
     was centring on its own width: the eyebrow at 139px, the tagline at 72px,
     the lead at 36px. Four different left edges reading as a centred column
     that was not centred. */
  .open__grid { align-items: flex-start; }
  .open__say .masthead,
  .open__tagline,
  .open__lead,
  .open__acts,
  .open__aside { align-self: stretch; }
  /* .verse sits later in this file than the order block, so its own
     margin-top won on specificity ties. Name the parent. */
  .open__aside .verse { margin-top: 0; }
  .open__aside { margin-top: var(--s-6); }
}

@media (min-width: 960px) {
  /* Optical alignment: the aside's first line and the eyebrow should start on
     the same line. The display serif's cap sits lower in its box than the
     uppercase body text does, so no top padding is the correct value. */
  .open__aside { padding-top: 0; }
}

/* Three lines breaking after "by" reads as a fault. Balanced, on a measure
   that lets it break at the comma. */
.open__verse p { max-width: 30ch; text-wrap: balance; }
.open__verse { max-width: 30ch; }


/* -- The action on a blue field, 2026-09-02 -------------------------------
   Deep logo blue on a deep logo blue field is invisible, so the button
   inverts to the mark's cyan with ink type. Both values come off the logo.
   The keyline stays: it is what bounds the block. ------------------------ */
.field .act {
  background: var(--raw-action-on-field);
  color: var(--raw-action-on-field-text);
}
.field .act:hover { background: var(--raw-wam-sky); color: var(--raw-action-on-field-text); }

/* -- The triptych panels are the routing, 2026-09-02 ----------------------
   Three photo cards under the triptych plus four pillars put seven boxes on
   a homepage the team had just said has too many. The panels themselves now
   carry the three destinations, which is what the written brief described:
   a triptych of the three manifestations that segues to the three paths. --- */
a.tri__panel { display: block; text-decoration: none; color: inherit; }
a.tri__panel:focus-visible { outline: 3px solid var(--raw-wam-sky); outline-offset: -4px; }
.tri__go {
  margin: var(--s-3) 0 0;
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: 700;
  color: var(--raw-wam-sky);
  border-bottom: 1px solid currentColor;
  display: inline-block;
  padding-bottom: 2px;
}
a.tri__panel:hover .tri__go { color: var(--raw-light); }
a.tri__panel:hover img { transform: scale(1.015); }
a.tri__panel img { transition: transform 400ms ease; }
@media (prefers-reduced-motion: reduce) { a.tri__panel img { transition: none; } a.tri__panel:hover img { transform: none; } }
.tri__note { margin-top: var(--s-3); }

/* ==========================================================================
   2026-09-03 · Content restructure from the team and Patrick's edits.

   No new design language. Every value below is an existing token. The hero
   layout is new because Kathy asked for it explicitly: text on the left
   third, image on the right two-thirds, bleeding to the right edge.
   ========================================================================== */

/* -- Hero: left third says it, right two-thirds shows it ------------------ */
.hero {
  display: grid;
  grid-template-columns: 1fr;
  background-color: var(--ground);
  background-image: var(--weave);
}
@media (min-width: 60rem) {
  .hero { grid-template-columns: minmax(0, 34fr) minmax(0, 66fr); align-items: stretch; }
}
.hero__say { display: flex; align-items: center; padding-block: var(--band-pad); }
.hero__inner {
  /* aligns to the same left margin as every .shell on the page */
  width: 100%;
  max-width: calc(var(--shell) * 0.34);
  margin-left: auto;
  /* padding-left is set in the spacing block near the end of this file */
  padding-right: var(--shell-pad);
  box-sizing: content-box;
}
@media (max-width: 59.99rem) {
  .hero__inner { max-width: none; margin-left: 0; }
}
.hero__inner h1 { margin-bottom: var(--s-4); }
.hero__handle {
  font-family: var(--font-body); font-size: var(--fs-lead); font-weight: 700;
  color: var(--text-accent); margin: 0 0 var(--s-2);
}
.hero__tag {
  font-family: var(--font-display); font-style: italic; font-weight: 500;
  font-size: var(--fs-d3); line-height: 1.2; color: var(--text-soft);
  margin: 0;
}
.hero__acts { margin-top: var(--s-7); }
.hero__plate { position: relative; min-height: clamp(17rem, 46vw, 34rem); overflow: hidden; }
.hero__plate img { width: 100%; height: 100%; object-fit: cover; object-position: center 30%; }
@media (max-width: 59.99rem) { .hero__say { order: 2; } .hero__plate { order: 1; min-height: 54vw; } }

/* -- The mission statement, set as a statement --------------------------- */
.mission {
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-d2); line-height: var(--lh-d2); letter-spacing: var(--tr-d2);
  max-width: 34ch; margin: 0;
}

/* -- Featured story / current response ----------------------------------- */
.feature { display: grid; gap: var(--s-7); margin-top: var(--s-6); }
@media (min-width: 62rem) {
  .feature { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-8); align-items: start; }
}
.feature__plate { margin: 0; }

/* -- The three names, side by side on the page rather than in the footer -- */
.crosstracks { display: grid; gap: var(--s-6); margin-top: var(--s-6); }
@media (min-width: 55rem) { .crosstracks { grid-template-columns: repeat(3, 1fr); gap: var(--s-7); } }
.crosstracks .crosstrack { border-top: 2px solid var(--seam-strong); padding-top: var(--s-4); }

/* -- Return to top. Kathy: any page that exceeds one screen -------------- */
.totop {
  display: block; width: max-content; margin: 0 auto;
  padding: var(--s-3) var(--s-5);
  font-family: var(--font-body); font-size: var(--fs-small); font-weight: 700;
  color: var(--text-accent); text-decoration: none;
  border: 1px solid var(--seam); border-radius: 2px;
  background: var(--ground);
}
.totop:hover { border-color: var(--action); }
.totop__wrap { padding-block: var(--s-7); background-color: var(--ground); background-image: var(--weave); }

/* -- Corrections, same day ------------------------------------------------ */

/* The hero text must sit on the same left margin as every .shell below it,
   or the page has two left edges. */
.hero__say { padding-left: max(var(--shell-pad), calc((100vw - var(--shell)) / 2)); }
.hero__inner { max-width: none; margin-left: 0; padding-right: var(--s-6); }
@media (max-width: 59.99rem) {
  .hero__say { padding-left: var(--shell-pad); }
  .hero__inner { padding-right: 0; }
}

/* The give grid sets its own top rules, so the lead above it needs clearance. */
.give__grid { margin-top: var(--s-8); }

/* A figure placed in a two-column grid needs its image to fill the column. */
.feature__plate img { display: block; width: 100%; height: auto; }

/* A .prose block immediately after a heading needs the heading's own rhythm. */
.d2 + .prose, .d3 + .prose, .lead + .prose { margin-top: var(--s-5); }

/* Three buckets in a two-column grid leaves a hole. */
@media (min-width: 62rem) { .pillars--three { grid-template-columns: repeat(3, 1fr); } }

/* ==========================================================================
   4 September · three corrections from the deployed hero.
   ========================================================================== */

/* -- 1. The logo, and the bar it sits in.
   The header SVG carried its artwork inside a box roughly 60% empty, so the
   only way to make the mark look right was to blow the box up to 248px, which
   made the sticky bar 160px tall. The viewBox is now trimmed to the artwork
   and matches white-horizontal.svg, so the mark renders at the same visible
   size in a box less than half as tall. Do not re-export either file without
   a trimmed viewBox. ------------------------------------------------------ */
.head__mark img { width: clamp(160px, 14vw, 186px); }
.head__bar { padding-block: var(--s-3); }
@media (max-width: 899px) {
  .head__mark img { width: clamp(140px, 34vw, 172px); }
  .head__bar { padding-block: var(--s-2); }
}

/* -- 2. Everything was squished to the left.
   The hero ran 34/66, which left the text roughly 350px of usable column at
   1440 and forced "Witness as Ministry" onto three cramped lines. The
   measures elsewhere were set narrow enough to leave standing voids on the
   right of every band. Both widened. ------------------------------------- */
@media (min-width: 60rem) {
  .hero { grid-template-columns: minmax(0, 44fr) minmax(0, 56fr); }
}
.hero__inner h1 { max-width: 12ch; }
.hero__inner { padding-right: var(--s-7); }

:root {
  --measure: 72ch;
  --measure-narrow: 58ch;
}
.who__grid > * > .prose, .who__grid > .prose { max-width: none; }

/* Two-column bands were running 1fr 1fr with narrow measures inside, so the
   text stopped well short of the column. Let the columns carry their text. */
@media (min-width: 60rem) {
  .who__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-8); }
}

/* -- 3. The triptych sits under the hero now, so it needs a little less
   -- height than it had as the page's opening image. ---------------------- */
.tri__panel { min-height: clamp(16rem, 34vw, 25rem); }
@media (max-width: 53.99rem) { .tri__panel { min-height: min(42vh, 20rem); } }

/* The mission statement is the band's whole content, so it takes the room. */
.mission--wide { max-width: 46ch; }

/* -- Hero block, spacing. 4 September ------------------------------------
   The original .hero__inner rule asked for padding-left: var(--seam-inset),
   a token that does not exist in this build, so the declaration was dropped
   and the block computed to zero left padding. Every line sat flush against
   the 2px seam and the Give button covered it. Content now clears the rule
   at exactly the same offset the .shell.seamed bands use, so the hero text
   and the band text below it share one left edge. ------------------------ */
.hero__inner { padding-left: var(--s-7); }
/* .seamed drops to --s-4 below 760px, so the hero must match it or the
   phone has two left edges. */
@media (max-width: 759px) { .hero__inner { padding-left: var(--s-4); } }

/* Two lines of 84px display at a 0.99 line-height, with a descender in
   "Ministry", closes up too far at this size. */
.hero__inner h1 { line-height: 1.05; margin-bottom: var(--s-6); }

/* The handle and the tagline are a pair, so they stay close to each other
   and take their air from the headline above and the actions below. */
.hero__handle { margin-bottom: var(--s-2); }
.hero__tag { margin-bottom: 0; }
.hero__acts { margin-top: var(--s-8); }

/* ==========================================================================
   ACCESSIBILITY PASS · 4 September 2026
   WCAG 2.1 AA, plus 2.5.8 from 2.2. Measured by build/a11y.py across 15 pages
   at 1440, 400, and 320px. No token, colour, or typeface changed: every value
   below is an existing token and the branding is untouched.
   ========================================================================== */

/* -- 1.4.10 Reflow ·  FAIL on all 15 pages -------------------------------
   At 320px the header ran 36px past the viewport, so every page had a
   horizontal scrollbar. Cause: the mark at 140px, plus a 32px gap, plus the
   Give button and the menu toggle, needed 316px of a 280px row. The earlier
   audits only tested 400px, which is why this survived.
   Below 360px the mark and the row gaps step down. ----------------------- */
@media (max-width: 22.5rem) {
  .head__bar { gap: var(--s-3); }
  .head__end { gap: var(--s-2); }
  .head__mark img { width: clamp(104px, 32vw, 128px); }
  .head__end .act { padding-inline: var(--s-4); font-size: var(--fs-small); }
}

/* -- 2.5.8 Target Size (Minimum) ·  FAIL --------------------------------
   Several links that are not inside a sentence measured 16 to 23px tall, so
   they fall under the 24px floor with no inline exception to lean on. Hit
   area only: nothing moves visually except where noted. ------------------ */

/* The quiet action sat at 23px next to a 56px button, which failed the floor
   and looked mismatched beside it. Now it matches the button's height, which
   is a visual improvement as much as an accessible one. */
.act-quiet { min-height: 2.75rem; padding-block: var(--s-3); }
.acts .act-quiet { min-height: 3.5rem; }

/* Breadcrumbs: 16px tall. Padded to clear the floor without moving the row. */
.crumb { display: flex; flex-wrap: wrap; align-items: center; }
.crumb a { display: inline-flex; align-items: center; min-height: 1.75rem; }

/* The footer address link, 17px tall on all 15 pages. */
.foot address a, address a {
  display: inline-flex; align-items: center; min-height: 1.75rem;
}

/* Footer list links are inside <li>, so 2.5.8's inline exception applies and
   they do not fail. They were still 17px, which is a poor thumb target on a
   phone, so they get the same treatment. */
.foot li a { display: inline-flex; align-items: center; min-height: 1.75rem; }

/* -- 2.5.5 Target Size (Enhanced) ·  advisory, taken anyway -------------
   Nav links were 42px and the social icons 40px. Both now clear 44, which is
   the platform guidance on both iOS and Android and the thing Kathy asked
   for when she said it has to be easy to use on a phone. ---------------- */
.nav a { min-height: 2.75rem; display: inline-flex; align-items: center; }
.social a, .foot__social a {
  min-width: 2.75rem; min-height: 2.75rem;
  display: inline-flex; align-items: center; justify-content: center;
}
.menu { min-width: 2.75rem; min-height: 2.75rem; }

/* -- 1.4.12 Text Spacing ·  warn -----------------------------------------
   The tight line-heights flagged were all display lines set in <p>: the
   mission statement at 1.07, the figures at 1.00, the verse at 1.18. Those
   are headings by function and the criterion addresses blocks of text, so
   they stand. The one genuine body case is the quiet note beneath the give
   actions, which was 1.30. ---------------------------------------------- */
.note, .qual { line-height: 1.55; }

/* .trust__links is a flex row, so its links are flex items rather than words
   in a sentence. 2.5.8's inline exception does not cover them and they
   measured 23px. */
.trust__links a { display: inline-flex; align-items: center; min-height: 1.75rem; }

/* ==========================================================================
   REDESIGN · 4 September 2026
   Reference: jwcouchfoundation.org, named twice in Kathy's feedback. What
   she is responding to there is structural, not stylistic: a full-bleed
   moving hero with the words over it, sparse sections each opening on a
   small label, and a single closing call to action.

   Branding is unchanged. Cloth, indigo, the logo blues, the gold seam,
   Alegreya over Alegreya Sans, the 3px radius: all as they were. Content is
   unchanged. This is treatment only.
   ========================================================================== */

/* -- The stage. Full bleed, the words on top. ---------------------------- */
.stage {
  position: relative;
  display: grid;
  align-items: end;
  min-height: clamp(30rem, 78vh, 46rem);
  overflow: hidden;
  /* resolves for the contrast tool and covers the frame before paint */
  background-color: var(--field-indigo);
}
.stage__media { position: absolute; inset: 0; }
.stage__video,
.stage__poster {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 32%;
}
.stage__video { z-index: 1; }
/* The poster sits under the video, so a missing or unplayable file simply
   shows the photograph. It also carries the alt text, because the video is
   decorative and aria-hidden. */
.stage__poster { z-index: 0; }

/* Text over a photograph needs a floor it can rely on. The gradient is
   bottom-weighted so the faces in the upper two thirds stay readable and the
   words sit on the darkest part of the frame. */
.stage__scrim {
  position: absolute; inset: 0; z-index: 2;
  background:
    linear-gradient(to top,
      rgba(11, 58, 97, 0.94) 0%,
      rgba(11, 58, 97, 0.86) 22%,
      rgba(11, 58, 97, 0.42) 52%,
      rgba(11, 58, 97, 0.20) 78%,
      rgba(11, 58, 97, 0.28) 100%);
}

.stage__say { position: relative; z-index: 3; padding-block: var(--s-9) var(--s-8); }
.stage__inner { text-align: center; max-width: 54rem; }

.stage__title {
  color: var(--raw-light);
  margin-bottom: var(--s-4);
  text-wrap: balance;
  text-shadow: 0 1px 26px rgba(11, 58, 97, 0.55);
}
.stage__tag {
  font-family: var(--font-display); font-style: italic; font-weight: 500;
  font-size: var(--fs-d3); line-height: 1.2;
  color: var(--raw-light); margin: 0 0 var(--s-3);
  text-shadow: 0 1px 20px rgba(11, 58, 97, 0.5);
}
.stage__handle {
  font-family: var(--font-body); font-size: var(--fs-small); font-weight: 700;
  letter-spacing: 0.06em; text-transform: lowercase;
  color: var(--raw-wam-sky); margin: 0;
}
.stage__acts { justify-content: center; margin-top: var(--s-7); }
.stage__quiet { color: var(--raw-light); }
.stage__quiet:hover { color: var(--raw-wam-sky); }

/* -- 2.2.2 Pause, Stop, Hide.
   Motion that runs past five seconds needs a control. The button is revealed
   by script only when a video is actually playing, so a poster-only hero does
   not offer a pause button for something that is not moving. ------------- */
.stage__pause {
  position: absolute; z-index: 4; right: var(--s-5); bottom: var(--s-5);
  display: inline-flex; align-items: center;
  min-height: 2.75rem; padding: 0 var(--s-5);
  font-family: var(--font-body); font-size: var(--fs-small); font-weight: 700;
  color: var(--raw-light);
  background: rgba(11, 58, 97, 0.78);
  border: 1px solid rgba(251, 247, 240, 0.55);
  border-radius: var(--radius);
  cursor: pointer;
}
.stage__pause:hover { background: rgba(11, 58, 97, 0.94); }
.stage__pause[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .stage__video { display: none; }
}

@media (max-width: 47.99rem) {
  .stage { min-height: clamp(26rem, 68vh, 34rem); }
  .stage__say { padding-block: var(--s-8) var(--s-7); }
  .stage__pause { right: var(--s-4); bottom: var(--s-4); }
}

/* -- Section rhythm, in the reference's manner ----------------------------
   Their sections are sparse and each opens on a small label above the
   heading. WAM already has that label as .masthead step, so the change is
   air, not furniture. The gold seam stays: it is the signature, and their
   centred composition is not what Kathy praised. --------------------------- */
.band { padding-block: clamp(4rem, 8vw, 8.5rem); }

/* The three, as pillar cards with a way in, rather than as a photo strip. */
.tri { gap: 1px; }
.tri__panel { min-height: clamp(17rem, 32vw, 24rem); }
.tri__cap { padding-bottom: clamp(1.15rem, 2.2vw, 2rem); }
.tri__go {
  margin-top: var(--s-4);
  min-height: 1.75rem; display: inline-flex; align-items: center;
}

/* The closing band is the one other place the reference's centring earns its
   keep: an exit should feel like an invitation, not a column of copy. */
.band--invite .shell { text-align: center; }
.band--invite .shell > * { margin-inline: auto; }
.band--invite .give__grid { text-align: left; }

/* -- Stage, refinements --------------------------------------------------
   The scrim was darkening the upper frame more than the text needed, which
   cost the faces. The dark is now concentrated in the lower third where the
   words actually sit. Measured: at the text position the scrim runs 0.86 to
   0.94 over the photograph, so even against a blown-out sky the composite is
   about #234E71 and white type on it holds 7.9:1. --------------------- */
.stage__scrim {
  background:
    linear-gradient(to top,
      rgba(11, 58, 97, 0.94) 0%,
      rgba(11, 58, 97, 0.88) 26%,
      rgba(11, 58, 97, 0.44) 50%,
      rgba(11, 58, 97, 0.12) 74%,
      rgba(11, 58, 97, 0.18) 100%);
}

/* The handle now labels the name rather than trailing the tagline. */
.stage__handle {
  margin: 0 0 var(--s-4);
  font-size: var(--fs-small);
  letter-spacing: 0.14em;
  text-transform: none;
  color: var(--raw-wam-sky);
}
.stage__tag { margin-bottom: 0; }

/* A paired secondary action, as the reference has, rather than an underlined
   link that reads as weaker than its sibling. Outline only: the fill, the
   type, and the radius are the existing button. */
.act--outline {
  background: transparent;
  color: var(--raw-light);
  box-shadow: inset 0 0 0 1.5px rgba(251, 247, 240, 0.72);
}
.act--outline:hover {
  background: rgba(251, 247, 240, 0.12);
  color: var(--raw-light);
  box-shadow: inset 0 0 0 1.5px var(--raw-light);
}

/* -- Stage, contrast correction ------------------------------------------
   The handle in sky blue sat at roughly 42% up the frame, where the scrim is
   thin. Composited over a bright part of the photograph that measures about
   2.1:1, which fails. Two changes: the whole text zone now sits under at
   least 0.80 of scrim, and the handle takes the light type rather than the
   sky, which is reserved for solid fields where it measures properly.
   Worst case now, sky-blown photograph under 0.80 scrim, composite ≈ #3C6181
   and light type on it holds 6.1:1. ------------------------------------- */
.stage__scrim {
  background:
    linear-gradient(to top,
      rgba(11, 58, 97, 0.95) 0%,
      rgba(11, 58, 97, 0.90) 34%,
      rgba(11, 58, 97, 0.82) 54%,
      rgba(11, 58, 97, 0.34) 72%,
      rgba(11, 58, 97, 0.14) 88%,
      rgba(11, 58, 97, 0.20) 100%);
}
.stage__handle { color: var(--raw-light); opacity: 0.92; }

/* The page-head lead was dropping a single word onto its own line. */
.pagehead__title + .lead { text-wrap: pretty; }

/* The three categories are a progression, not a menu, so they are numbered.
   Uses the eyebrow's own type treatment: no new design language. */
.pillar__step {
  font-family: var(--font-body);
  font-size: 0.75rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text-accent);
  margin: 0 0 var(--s-2);
}
.field .pillar__step { color: var(--text-on-field-accent); }

/* The three descriptions differ in length, so the item lists were starting at
   three different heights and the set did not scan as a set. The description
   absorbs the difference and the lists align. */
.pillar { display: flex; flex-direction: column; }
.pillar__why { flex: 1 1 auto; }

/* flex: 1 on the description aligns the list bottoms, and with 3, 4, and 5
   items that still leaves three different starting heights. Subgrid aligns
   every band across the three cards: numeral, name, description, list.
   The flex rule above stays as the fallback. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 62rem) {
    /* row-gap would otherwise apply between the subgrid rows as well as
       between the cards, so the elements' own margins do the vertical
       spacing and the column gap is preserved. */
    .pillars--three { grid-template-rows: auto auto auto auto; row-gap: 0; }
    .pillars--three .pillar {
      display: grid;
      grid-row: span 4;
      grid-template-rows: subgrid;
      align-content: start;
    }
  }
}

/* -- Why We Care, revised copy 4 September -------------------------------
   The section now ends on two short lines rather than a display sentence,
   so the payoff sits full width beneath the two columns of prose. */
.why__stay {
  margin-top: clamp(2.5rem, 5vw, 4.5rem);
  max-width: 30ch;
}
.why__promise {
  margin-top: var(--s-4);
  font-family: var(--font-body);
  font-size: var(--fs-lead);
  color: var(--text-soft);
  max-width: 40ch;
}

/* Each expression now carries its own way in, so the link needs to sit at the
   foot of the block rather than in the flow of the description. */
.crosstracks .crosstrack { display: flex; flex-direction: column; }
.crosstrack__go { margin-top: auto; padding-top: var(--s-4); margin-bottom: 0; }
.three__entity { max-width: none; margin-top: clamp(2.5rem, 5vw, 4rem); }
.three__entity .d3 { margin-bottom: var(--s-3); }

/* .stack is used in the markup but was never defined in this build, so
   stacked paragraphs ran together with no gap. */
.stack > * + * { margin-top: var(--s-5); }

/* ==========================================================================
   HERO / TRIPTYCH BLEND · 8 September 2026

   The seam between the two was the worst edge on the site: the hero ended at
   0.95 navy, essentially solid, and the triptych began at full untreated
   daylight. A flat wash on one side, a contact sheet on the other.

   Three changes, in order of what they fix:

   1. The hero scrim stops being a filter. A light global wash lets the
      photograph read, and a soft ellipse carries the contrast where the type
      actually sits. Same ratio, a fifth of the murk.
   2. The boundary becomes a dissolve. The hero now bottoms out at 0.74 and
      each triptych panel opens at 0.72, so the tone runs continuously across
      the edge instead of stepping off it.
   3. The three photographs get one treatment, so they read as a set rather
      than as three different afternoons.
   ========================================================================== */

/* -- 1. Lighting, not filtering -----------------------------------------
   Measured. Global wash at the text zone is about 0.70; the ellipse adds
   0.58 over it, which composites to 1-(0.30 x 0.42) = 0.87. That is higher
   than the flat 0.82 it replaces, so type contrast improves while the top of
   the frame drops from 0.90 to 0.26 and the faces come back.

   Worst case, light type on 0.87 navy over a blown-out sky, composites to
   about #2A5171 and holds 8.0:1. ---------------------------------------- */
.stage__scrim {
  background:
    radial-gradient(125% 72% at 50% 74%,
      rgba(11, 58, 97, 0.58) 0%,
      rgba(11, 58, 97, 0.36) 46%,
      rgba(11, 58, 97, 0.00) 74%),
    linear-gradient(to top,
      rgba(11, 58, 97, 0.74) 0%,
      rgba(11, 58, 97, 0.70) 18%,
      rgba(11, 58, 97, 0.58) 40%,
      rgba(11, 58, 97, 0.34) 62%,
      rgba(11, 58, 97, 0.22) 82%,
      rgba(11, 58, 97, 0.26) 100%);
}
/* The photograph was also being flattened by the scrim sitting on top of a
   full-colour image. A touch of lift underneath keeps it from going muddy. */
.stage__poster,
.stage__video { filter: saturate(0.94) contrast(1.04) brightness(1.02); }

/* -- 2. The edge, dissolved ---------------------------------------------
   Each panel opens at 0.72 navy and clears by roughly two thirds down, which
   picks up where the hero leaves off. Read together, the tone now runs
   dark, clearing, photograph, dark caption: one composition across the seam
   rather than two blocks meeting at a line. ----------------------------- */
/* First attempt matched the alphas, 0.74 above and 0.72 below, and the step
   was still visible: alpha is not the thing the eye compares, luminance is.
   The hero's lower edge sits over dark clothing and a shadowed sack; the
   panels sit over yellow hi-vis, white limestone and a white greenhouse
   frame. Equal alpha over brighter photographs reads lighter. The panels
   therefore open darker than the hero closes, and clear faster. */
.tri__panel::before {
  content: '';
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to bottom,
    rgba(11, 58, 97, 0.90) 0%,
    rgba(11, 58, 97, 0.62) 16%,
    rgba(11, 58, 97, 0.30) 36%,
    rgba(11, 58, 97, 0.10) 54%,
    rgba(11, 58, 97, 0.00) 70%);
}

/* -- 3. One treatment for three afternoons ------------------------------
   Yellow hi-vis, warm limestone, bright hydroponic green. Pulling the
   saturation back and letting the shared navy sit over all three makes them a
   set. The greenhouse was the loudest, so it comes back furthest. ------- */
.tri__panel img { filter: saturate(0.82) contrast(1.03); }
.tri__panel:last-child img { filter: saturate(0.62) contrast(1.03) brightness(0.90); }

/* The captions sat on their own gradient, which now doubles up with the top
   one. Lighten it so the lower third does not go solid. */
.tri__panel::after {
  background: linear-gradient(to top,
    rgba(11, 58, 97, 0.86) 0%,
    rgba(11, 58, 97, 0.52) 34%,
    rgba(11, 58, 97, 0.00) 62%);
}

/* ==========================================================================
   HERO / TRIPTYCH BLEND, second approach · 8 September 2026

   Matching alphas across the seam does not work, and the arithmetic says why.
   Navy #0B3A61 has a luminance of 48; the panel photographs average about 159
   where they meet the hero. Equal alpha over a brighter photograph reads
   lighter, so closing the 12-point gap needed an alpha of 1.005 — a solid
   navy strip across the top of all three panels, which is not a blend, it is
   a lid.

   So the premise changes. Instead of darkening one side to meet the other,
   both sides get a light wash and the type gets its own plate. The seam
   becomes photograph meeting photograph, which needs no blending, and the
   contrast stops depending on where the gradient happens to be strong.
   ========================================================================== */

/* -- The wash is now light, and even ------------------------------------- */
.stage__scrim {
  background: linear-gradient(to top,
    rgba(11, 58, 97, 0.34) 0%,
    rgba(11, 58, 97, 0.28) 40%,
    rgba(11, 58, 97, 0.20) 74%,
    rgba(11, 58, 97, 0.26) 100%);
}

/* -- The type sits on its own plate --------------------------------------
   A soft-edged ellipse that hugs the text rather than a band across the
   frame. It has no visible edge, and it makes the contrast a fixed property
   of the text block instead of a function of the photograph behind it.

   Measured, worst case: the wash puts a blown-out sky at about #42689 0, the
   plate at 0.80 over that composites to roughly #17446A, and light type on
   it holds 9.4:1. That is better than any version of the full-frame gradient
   managed, on a frame that is a third as dark. ---------------------------- */
.stage__inner {
  padding: clamp(2.25rem, 5vw, 4rem) clamp(1.75rem, 5vw, 4.5rem);
  background: radial-gradient(closest-side ellipse at 50% 52%,
    rgba(11, 58, 97, 0.86) 0%,
    rgba(11, 58, 97, 0.80) 48%,
    rgba(11, 58, 97, 0.52) 74%,
    rgba(11, 58, 97, 0.00) 100%);
}

/* An outlined button over photography needs a ground of its own, or its label
   depends on whatever is behind it. */
.act--outline { background: rgba(11, 58, 97, 0.55); }
.act--outline:hover { background: rgba(11, 58, 97, 0.78); }

/* -- The panels take the same light wash, so the seam is two photographs
   -- under one treatment rather than a step between two systems. --------- */
.tri__panel::before {
  background: linear-gradient(to bottom,
    rgba(11, 58, 97, 0.38) 0%,
    rgba(11, 58, 97, 0.26) 30%,
    rgba(11, 58, 97, 0.14) 58%,
    rgba(11, 58, 97, 0.06) 80%);
}
.tri__panel img { filter: saturate(0.86) contrast(1.02); }
.tri__panel:last-child img { filter: saturate(0.70) contrast(1.02) brightness(0.94); }

/* ==========================================================================
   HERO / TRIPTYCH BLEND, the actual fix · 8 September 2026

   Two gradient attempts, and the measurements killed both. Matching alphas
   left a 12-point luminance step; lighting both sides evenly made it 57,
   because the hero's lower edge happens to fall on dark clothing and a
   shadowed sack while the panels are yellow hi-vis and white limestone.

   The mismatch is the photographs, not the treatment. No gradient fixes two
   images of different brightness butted against each other, which is why
   this kept looking wrong however the numbers were tuned.

   So they stop being butted. The panels become three plates on the cloth
   ground, with the weave breathing above, between and below them. The hero
   now ends against cloth, which is an ordinary clean edge, and the plates
   read as a set below it. It also puts them in the brand's own idiom: every
   other photograph on this site is a plate on cloth with a printed lift.
   ========================================================================== */
.tri {
  background-color: var(--ground);
  background-image: var(--weave);
  padding: clamp(2.25rem, 5vw, 4.5rem) clamp(1rem, 3vw, 3rem);
  gap: clamp(1rem, 2vw, 1.75rem);
}
.tri__panel {
  min-height: clamp(15rem, 27vw, 21rem);
  box-shadow: var(--lift-photo);
}

/* With no seam to reconcile, the top wash exists only to keep the plates
   reading as one set rather than three separate afternoons. */
.tri__panel::before {
  background: linear-gradient(to bottom,
    rgba(11, 58, 97, 0.20) 0%,
    rgba(11, 58, 97, 0.10) 34%,
    rgba(11, 58, 97, 0.04) 62%);
}
.tri__panel::after {
  background: linear-gradient(to top,
    rgba(11, 58, 97, 0.88) 0%,
    rgba(11, 58, 97, 0.54) 38%,
    rgba(11, 58, 97, 0.00) 66%);
}

/* The hero's own bottom edge no longer has to reach for anything below it. */
.stage__scrim {
  background: linear-gradient(to top,
    rgba(11, 58, 97, 0.30) 0%,
    rgba(11, 58, 97, 0.26) 44%,
    rgba(11, 58, 97, 0.18) 76%,
    rgba(11, 58, 97, 0.24) 100%);
}

/* Moving the ground to .tri left each panel with no background of its own, so
   a panel whose photograph failed to load would render light caption text on
   cloth: 1.01:1. The plates carry their own indigo again, which is also what
   the caption gradients are drawn against. */
.tri__panel {
  background-color: var(--field-indigo);
  background-image: var(--weave);
}

/* ==========================================================================
   FOOTER, compressed · 8 September 2026 · Kathy item 9

   It was 743px on desktop and 1,610px on a phone, which is 20% of the
   homepage. It also repeated the entire top menu, which she had already
   objected to, and carried the Dovetail and Wamhiba blurbs that are now a
   full section on the homepage at Diane's request.

   Two rows instead of three columns: identity on the left, one wrapping row
   of links on the right, legal underneath. Nothing essential removed. Her
   own proposal was cut off mid-sentence, so this is the defensible version
   of what she asked for rather than the version she specified.
   ========================================================================== */
.foot__top {
  display: grid; gap: var(--s-6);
  grid-template-columns: 1fr;
  padding-bottom: var(--s-6);
}
@media (min-width: 55rem) {
  .foot__top {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--s-8); align-items: start;
  }
}
.foot__id address { margin: var(--s-4) 0 var(--s-4); font-style: normal; }
.foot__links {
  display: flex; flex-wrap: wrap;
  gap: var(--s-3) var(--s-6);
  align-content: start;
}
.foot__links a { display: inline-flex; align-items: center; min-height: 1.75rem; }
@media (min-width: 55rem) { .foot__links { justify-content: flex-end; } }

/* ==========================================================================
   PRODUCTION NOTES · 8 September 2026

   .pending was created to hold build flags in the page while the content was
   being settled: photo releases, unverified addresses, figures awaiting
   reconciliation. It renders as visible italic text, which was right during
   review and is wrong now. Twenty-one of them were showing on eleven pages,
   including instructions addressed to me, a filename, and a staff member's
   name.

   They are worth keeping, so they are gated rather than deleted. Hidden by
   default; add ?review to any URL to see them all. The team keeps its review
   tool and a donor never reads "[PHOTO RELEASE REQUIRED]" under a photograph.
   ========================================================================== */
.pending { display: none; }
html.review .pending {
  display: inline;
  font-style: italic;
  color: var(--text-soft);
  background: rgba(201, 169, 106, 0.22);
  box-shadow: 0 0 0 2px rgba(201, 169, 106, 0.22);
  border-radius: 2px;
}
html.review .field .pending,
html.review .stage .pending { color: var(--raw-light-soft); }

/* An empty .pending, left where a figure will go, should not reserve space. */
.pending:empty { display: none !important; }

/* ==========================================================================
   FOOTER · Kathy's mock-up, 8 September 2026
   WAM INC as the parent, then each public identity with its own mark and
   channels, so the umbrella relationship is visible rather than only stated
   in the legal line beneath. Four across on desktop, two on a tablet, one on
   a phone.
   ========================================================================== */
.foot__grid {
  display: grid; gap: var(--s-7) var(--s-6);
  grid-template-columns: 1fr;
  padding-bottom: var(--s-6);
}
@media (min-width: 34rem) { .foot__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 62rem) {
  .foot__grid { grid-template-columns: 1.15fr 1fr 1fr 1fr; gap: var(--s-8) var(--s-7); }
}

.footbrand { display: flex; flex-direction: column; align-items: flex-start; }
.footbrand__parent {
  font-family: var(--font-display); font-weight: 800;
  font-size: 1.375rem; letter-spacing: -0.01em;
  margin: 0 0 var(--s-4); color: var(--text-on-field);
}
.footbrand address { font-style: normal; margin: 0 0 var(--s-4); font-size: var(--fs-small); }
.footbrand__mark { display: block; margin-bottom: var(--s-4); }
.footbrand__mark img { width: clamp(132px, 13vw, 164px); height: auto; }
.footbrand__name {
  font-family: var(--font-body); font-weight: 700; font-size: var(--fs-small);
  margin: 0 0 var(--s-2);
}
.footbrand__name a { color: var(--text-on-field); text-decoration: none; border-bottom: 1px solid transparent; }
.footbrand__name a:hover { border-bottom-color: var(--text-on-field-accent); }
.footbrand__contact { font-size: var(--fs-small); margin: 0; }
.footbrand .social { margin-top: var(--s-5); }

/* The parent column reads as the parent: slightly stronger, and set apart on
   the widths where there is room for a rule. */
@media (min-width: 62rem) {
  .footbrand--parent { padding-right: var(--s-6); border-right: 1px solid var(--seam-indigo); }
}

/* The closing line: legal, then the two links the mock-up does not carry but
   a donor page should, then the locations. */
.foot__meta {
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-6);
  align-items: center; margin: 0;
}
.foot__meta a { display: inline-flex; align-items: center; min-height: 1.75rem; }

/* A footer mark whose logo file does not exist yet collapses, so the brand
   name in type below it carries the column on its own. */
.footbrand__mark.is-empty { display: none; }
/* Same for the leadership portrait: the caption still explains what is coming. */
.photo.is-empty, figure.is-empty { min-height: 0; }

/* ==========================================================================
   FOOTER, light ground · 9 September 2026

   Not a preference. The supplied Dovetail file has no alpha channel at all,
   so on the indigo field it renders as a white rectangle, and both marks are
   colour lockups built for a light ground. Kathy's mock-up is on white for
   that reason, and the assets settle the question.

   The marks are also three different lockups: WAM horizontal at 2.90:1,
   Wamhiba horizontal at 2.69:1, and Dovetail stacked at 1.37:1. Matching
   them on width would leave Dovetail's wordmark tiny, so they are matched on
   the optical size of the wordmark instead, which means three different
   heights. Those numbers were tuned by eye, not calculated.
   ========================================================================== */
.foot--light {
  background-color: var(--ground-fold);
  background-image: var(--weave);
  color: var(--text);
  border-top: 1px solid var(--seam);
}
.foot--light .footbrand__parent { color: var(--text); }
.foot--light address,
.foot--light .footbrand__contact,
.foot--light .foot__end,
.foot--light .foot__end p { color: var(--text-soft); }
.foot--light .footbrand__name a { color: var(--text); }
.foot--light .footbrand__name a:hover { border-bottom-color: var(--action); }
.foot--light a { color: var(--text-accent); }
.foot--light .social a { border-color: var(--seam); color: var(--text-accent); }
.foot--light .social a:hover { border-color: var(--action); }
.foot--light .foot__end { border-top-color: var(--seam); }
@media (min-width: 62rem) {
  .foot--light .footbrand--parent { border-right-color: var(--seam); }
}

/* Three lockups, three heights, so the wordmarks read at the same size. */
.footbrand__mark img { width: auto; }
.footbrand--wam    .footbrand__mark img { height: 44px; }
.footbrand--dove   .footbrand__mark img { height: 76px; }
.footbrand--hiba   .footbrand__mark img { height: 46px; }
/* The stacked Dovetail lockup already contains its own name, so its column
   needs less air above the wordmark than the horizontal ones do. */
.footbrand--dove .footbrand__mark { margin-bottom: var(--s-3); }

/* -- Footer marks, alignment ---------------------------------------------
   Three lockups of different heights left the three brand names sitting on
   three different baselines, about 20px apart, which read as sloppy rather
   than as a set. The mark zone is now a fixed height with the marks sitting
   on its floor, so every name aligns regardless of lockup shape. --------- */
.footbrand__mark {
  height: 82px;
  display: flex; align-items: flex-end;
  margin-bottom: var(--s-4);
}
.footbrand--dove .footbrand__mark { margin-bottom: var(--s-4); }
/* Wamhiba's lockup tucks HYDROPONIC FARMS under the wordmark, so it needs
   more height than its aspect ratio suggests or that line disappears. */
.footbrand--hiba .footbrand__mark img { height: 58px; }

/* On a phone the four identity blocks stacked to 1,285px, which works against
   the very thing Kathy raised. Two across from 24rem halves it. */
@media (min-width: 24rem) and (max-width: 33.99rem) {
  .foot__grid { grid-template-columns: repeat(2, 1fr); gap: var(--s-6) var(--s-5); }
  .footbrand__mark { height: 66px; }
  .footbrand--dove .footbrand__mark img { height: 62px; }
  .footbrand--hiba .footbrand__mark img { height: 46px; }
  .footbrand--wam  .footbrand__mark img { height: 36px; }
}

/* ==========================================================================
   THE FEATURED STORY · 9 September 2026
   Person, then need, then unit, then button, in one band. The ask sits on a
   ruled shelf beneath the story rather than in a section of its own, so the
   handoff from a face to a hundred dollars happens without a scroll.
   ========================================================================== */
.story { display: grid; gap: var(--s-7); margin-top: var(--s-6); }
@media (min-width: 62rem) {
  .story { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: var(--s-8); align-items: start; }
}
.story__plate { margin: 0; }
.story__plate img { display: block; width: 100%; height: auto; }
.story__on { margin: var(--s-6) 0 0; }

.story__ask {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: var(--s-6);
  border-top: 2px solid var(--seam-strong);
  display: grid; gap: var(--s-5);
}
@media (min-width: 55rem) {
  .story__ask { grid-template-columns: auto minmax(0, 1fr); gap: var(--s-8); align-items: start; }
}
.story__unit { margin: 0; }
.story__amount {
  display: block; font-family: var(--font-display); font-weight: 700;
  font-size: clamp(2.75rem, 2rem + 3vw, 4.25rem); line-height: 0.95;
  letter-spacing: -0.03em;
}
.story__per { display: block; margin-top: var(--s-2); font-size: var(--fs-small); color: var(--text-soft); max-width: 18ch; }
.story__act p { max-width: 52ch; }
.story__act .acts { margin-top: var(--s-5); }

/* ==========================================================================
   STORIES FROM THE FIELD · 25 September 2026

   Thirty-one notes were one tall band of identical rows: no dates, no
   places, no photographs, no grouping. They are now a featured note with a
   real excerpt, a country filter, and cards grouped by year. Titles are left
   exactly as the field wrote them. A note with a photograph in /assets/img/
   shows it; a note without one is a typographic plate on the gold seam,
   because a placeholder or a stock image would be worse than nothing.
   Layer 2 roles only; no hex literals.
   ========================================================================== */

/* The dateline: date, then place, small and tabular. Shared by the cards, the
   featured note and the homepage story. The separator is rendered only when
   both halves exist, so a hidden production marker never leaves an orphaned
   dot (the "hole" failure from the 8 September marker pass). */
.notemeta {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-2) var(--s-3);
  margin: 0 0 var(--s-3);
  font-family: var(--font-body); font-size: var(--fs-small); font-weight: 600;
  letter-spacing: 0.02em; color: var(--text-soft);
  font-variant-numeric: tabular-nums lining-nums;
}
.notemeta__sep { color: var(--seam-strong); }
.field .notemeta { color: var(--text-on-field-soft); }

/* -- The featured note ---------------------------------------------------- */
.feat { display: grid; gap: var(--s-6); }
@media (min-width: 62rem) {
  .feat { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-9); align-items: center; }
}
.feat__plate { margin: 0; }
.feat__plate img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; }
.feat__title { margin-bottom: var(--s-4); }
.feat__title a { color: inherit; text-decoration: none; }
.feat__title a:hover { color: var(--text-accent); }
.feat__excerpt { max-width: var(--measure-narrow); color: var(--text); }
.feat__from { margin-top: var(--s-3); }
.feat__go { margin: var(--s-5) 0 0; }

/* -- The filter ----------------------------------------------------------- */
.notes__head { display: grid; gap: var(--s-5); margin-bottom: var(--s-6); }
@media (min-width: 62rem) {
  .notes__head { grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: var(--s-7); }
}
.filters { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.filters[hidden] { display: none; }
.filters__label { margin: 0 var(--s-2) 0 0; font-size: var(--fs-small); font-weight: 600; color: var(--text-soft); }
.filter {
  min-height: 2.75rem; padding: 0 var(--s-4);
  font-family: var(--font-body); font-size: var(--fs-small); font-weight: 600;
  color: var(--text-accent); background: transparent;
  border: 1px solid var(--seam-strong); border-radius: var(--radius);
  cursor: pointer;
  transition: background 160ms var(--ease-out), color 160ms var(--ease-out);
}
.filter:hover { background: var(--ground-fold); }
.filter[aria-pressed="true"] { background: var(--action); color: var(--action-text); border-color: var(--action); }
.filter-status { margin: 0 0 var(--s-6); min-height: 1.5em; }
/* Empty until a filter is chosen: it stays in the DOM as a live region but
   reserves no space, so the first year sits under the filter row. */
.filter-status:empty { margin: 0; min-height: 0; }

/* -- Years ---------------------------------------------------------------- */
.year { margin-top: var(--s-9); }
.year:first-of-type { margin-top: 0; }
.year[hidden] { display: none; }
.year__label {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-d2); line-height: 1;
  letter-spacing: var(--tr-d2); margin: 0 0 var(--s-5); padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--seam);
  font-variant-numeric: lining-nums;
}

/* -- Cards ---------------------------------------------------------------- */
.cards { display: grid; gap: var(--s-5); }
@media (min-width: 40rem) { .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 62rem) { .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-6); } }

.card {
  display: flex; flex-direction: column;
  text-decoration: none; color: inherit;
  background-color: var(--ground-fold); background-image: var(--weave);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  overflow: hidden;
  transition: box-shadow 180ms var(--ease-out);
}
.card[hidden] { display: none; }
.card:hover { box-shadow: var(--lift-photo); }
.card:hover .card__title { color: var(--text-accent); }
.card__plate { display: block; }
.card__plate img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; }
.card__body { display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-5); flex: 1 1 auto; }
.card__body .notemeta { margin: 0; }
.card__title {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-d3);
  line-height: 1.22; letter-spacing: var(--tr-d3); text-wrap: balance;
  transition: color 160ms var(--ease-out);
}
.card__blurb { color: var(--text-soft); line-height: 1.5; }
.card__body .note { margin-top: auto; padding-top: var(--s-3); }
/* No photograph: the title carries the card, on the seam. */
.card--type .card__body { border-left: 2px solid var(--seam-strong); padding-block: var(--s-6); }
.card--type .card__title { font-size: clamp(1.45rem, 1.25rem + 0.7vw, 1.85rem); }

/* ==========================================================================
   OUR IMPACT · 25 September 2026
   Two rows of four figures, each with its source and year, then one field
   photograph at a time in a fixed frame: a slow fade, several seconds' hold,
   a pause control, no arrows, no dots. Under prefers-reduced-motion nothing
   fades; every photograph is simply laid out and the control goes away.
   ========================================================================== */
.figrows { display: grid; gap: var(--s-8); }
.figrow__label {
  margin: 0 0 var(--s-2);
  font-family: var(--font-body); font-size: var(--fs-small); font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-soft);
}

.seq { position: relative; }
.seq__frame { margin: 0; }
.seq__frame img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 16 / 9; object-fit: cover;
  box-shadow: var(--lift-photo);
}
.seq__frame figcaption { margin-top: var(--s-3); }
/* Script absent: the first photograph stands alone, nothing moves. */
html:not(.js) .seq__frame:not(:first-child) { display: none; }
/* Script present: the frames stack in one cell and cross-fade. Visibility is
   delayed by the fade so the outgoing frame is not yanked mid-dissolve. */
html.js .seq__frames { display: grid; }
html.js .seq__frame {
  grid-area: 1 / 1;
  opacity: 0; visibility: hidden;
  transition: opacity 1400ms var(--ease-out), visibility 0s linear 1400ms;
}
html.js .seq__frame[data-active="true"] { opacity: 1; visibility: visible; transition-delay: 0s, 0s; }

.seq__bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s-3) var(--s-5); margin-top: var(--s-5);
}
.seq__bar[hidden] { display: none; }
.seq__count { margin: 0; font-variant-numeric: tabular-nums; }
.seq__toggle {
  min-height: 2.75rem; padding: 0 var(--s-5);
  font-family: var(--font-body); font-size: var(--fs-small); font-weight: 700;
  color: var(--text-accent); background: transparent;
  border: 1px solid var(--seam-strong); border-radius: var(--radius);
  cursor: pointer;
  transition: background 160ms var(--ease-out);
}
.seq__toggle:hover { background: var(--ground-fold); }

@media (prefers-reduced-motion: reduce) {
  html.js .seq__frames { grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: var(--s-6); }
  html.js .seq__frame { grid-area: auto; opacity: 1; visibility: visible; transition: none; }
  .seq__bar { display: none; }
}

/* ==========================================================================
   HOMEPAGE RHYTHM · 25 September 2026
   Every band was 700 to 950px and opened eyebrow, heading, prose: one tempo
   for six sections. The story band now opens on the photograph, the
   partnership band runs shorter, and the story carries a dateline so it
   reads as a report from a place and a day rather than as marketing copy.
   ========================================================================== */
.band--tight { padding-block: clamp(3rem, 5.5vw, 5.5rem); }
.story__meta { margin-bottom: var(--s-3); }
@media (min-width: 62rem) {
  .story--plate-first { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); align-items: center; }
}

/* ==========================================================================
   FIELD NOTE PAGES · 25 September 2026
   The 31 published notes, rebuilt as static pages at their frozen slugs.
   The body is ordinary prose on the fold ground; photographs are the same
   plates the rest of the site uses; an ask inside a note is a ruled shelf,
   not a coloured box. Layer 2 roles only.
   ========================================================================== */
.notebody { max-width: var(--measure); }
.notebody > * + * { margin-top: var(--s-5); }
.notebody h2 { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-d3); line-height: var(--lh-d3); letter-spacing: var(--tr-d3); margin-top: var(--s-8); }
.notebody h3 { font-family: var(--font-display); font-weight: 600; font-size: 1.2rem; line-height: 1.3; margin-top: var(--s-7); }
.notebody h2:first-child, .notebody h3:first-child { margin-top: 0; }
.notebody ul, .notebody ol { padding-left: 1.4em; }
.notebody li + li { margin-top: var(--s-2); }
.notebody blockquote {
  margin: var(--s-6) 0; padding-left: var(--s-5);
  border-left: 2px solid var(--seam-strong);
  font-family: var(--font-display); font-size: var(--fs-lead); line-height: var(--lh-lead);
}
.notebody blockquote > * + * { margin-top: var(--s-3); }
.notebody hr { border: 0; border-top: 1px solid var(--seam); margin: var(--s-7) 0; }
.notebody .acts { margin-top: var(--s-6); }
.notebody .lead { color: var(--text); }

.notefig { margin: var(--s-7) 0; }
.notefig img { display: block; width: 100%; height: auto; box-shadow: var(--lift-photo); }
.notefig--lead { margin: var(--s-7) 0 0; max-width: var(--measure); }
.notefig--lead img { max-height: 36rem; object-fit: cover; }
.notefig figcaption:empty { display: none; }
/* A credit link in a caption is a target: 24px minimum (WCAG 2.2 SC 2.5.8). */
.notefig figcaption a { display: inline-flex; align-items: center; min-height: 1.5rem; }

/* A run of photographs, as a set rather than a carousel. */
.notegrid { display: grid; gap: var(--s-5); margin: var(--s-7) 0; }
@media (min-width: 40rem) { .notegrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.notegrid .notefig { margin: 0; }
.notegrid .notefig img { aspect-ratio: 3 / 2; object-fit: cover; }

/* The ask inside a note: a shelf on the seam, in WAM's own words. */
.noteask {
  margin: var(--s-8) 0;
  padding: var(--s-6) 0 var(--s-6) var(--s-6);
  border-left: 2px solid var(--seam-strong);
  border-top: 1px solid var(--seam);
  border-bottom: 1px solid var(--seam);
}
.noteask > * + * { margin-top: var(--s-4); }
.noteask__eyebrow { font-family: var(--font-body); font-size: var(--fs-small); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-soft); margin: 0; }
.noteask__title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-d3); line-height: var(--lh-d3); margin: 0; }
.noteask .acts { margin-top: var(--s-5); }

/* Newer and older, then the way back to the index. */
.notenav { display: grid; gap: var(--s-5); margin-top: var(--s-7); padding-top: var(--s-6); border-top: 1px solid var(--seam); }
@media (min-width: 40rem) { .notenav { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; } }
.notenav .act-quiet { grid-column: 1 / -1; justify-self: start; }
.notenav__a { display: flex; flex-direction: column; gap: var(--s-1); text-decoration: none; color: inherit; min-height: 2.75rem; }
.notenav__t { font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; line-height: 1.3; color: var(--text-accent); }
.notenav__a:hover .notenav__t { color: var(--raw-ink); }

/* Related notes, and child pages within a programme: a plain ruled list. */
.related { margin-top: var(--s-8); }
.related__list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--seam); }
.related__list li { border-bottom: 1px solid var(--seam); }
.related__list a {
  display: inline-flex; align-items: center; min-height: 2.75rem; padding-block: var(--s-2);
  font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; line-height: 1.3;
  color: var(--text-accent); text-decoration: none;
}
.related__list a:hover { color: var(--raw-ink); }

/* ==========================================================================
   GIVE, EMBEDDED · 25 September 2026
   The Kindful plugin renders its own iframe into .giveform__slot and brings
   its own styling. The job here is to give it room, keep the fallback
   legible until it loads, and stop the plugin's z-index (99999, inline) from
   riding over the site's sticky header.
   ========================================================================== */
.giveform { margin-top: var(--s-6); }
.fundpick { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); margin-bottom: var(--s-5); }
.fundpick__label { margin: 0 var(--s-2) 0 0; font-size: var(--fs-small); font-weight: 600; color: var(--text-soft); }
.giveform__slot { min-height: 34rem; }
.giveform__slot { max-width: 100%; overflow-x: hidden; }
.giveform__slot iframe {
  width: 100% !important; max-width: 100% !important; min-width: 0 !important;
  border: 0; display: block; z-index: 0 !important;
}
.giveform__fallback { margin: 0 0 var(--s-4); }
.giveform__hint { color: var(--text-soft); }
.giveform__legal { margin-top: var(--s-6); max-width: 64ch; }
.giveform__legal a { color: var(--text-accent); }

/* ==========================================================================
   PHOTOGRAPHS SUPPLIED 25 SEPTEMBER 2026
   A plate in the page head's second column, and portraits beside the bios.
   ========================================================================== */
.pagehead__plate { margin: 0; }
.pagehead__plate img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; box-shadow: var(--lift-photo); }
.portrait { margin: 0; max-width: 18rem; }
.portrait img { display: block; width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; box-shadow: var(--lift-photo); }
.portraits { display: grid; gap: var(--s-6); align-content: start; }
@media (min-width: 960px) {
  .who__grid .portrait,
  .who__grid .portraits { align-self: start; }
  .who__grid .photo.portrait picture { min-height: 0; max-height: none; }
  .who__grid .photo.portrait img { height: auto; }
}
@media (min-width: 960px) {
  .who__grid .portraits .photo picture { min-height: 0; max-height: none; }
  .who__grid .portraits .photo img { height: auto; }
}

/* ==========================================================================
   GIVE, FULL PAGE · 25 September 2026
   The form on one side, the reason to give on the other: a photograph, the
   three sourced figures, and one line. Below, the three commitments as
   photographed cards. The plugin's frame is fixed at 1000px by Kindful, so
   the column beside it carries the weight the frame leaves empty.
   ========================================================================== */
.givehero { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-8); margin-top: var(--s-6); }
.givehero > * { min-width: 0; }   /* an auto track would grow to the photograph's 2000px */
@media (min-width: 62rem) {
  .givehero { grid-template-columns: minmax(0, 1fr) minmax(30rem, 34rem); gap: var(--s-9); align-items: start; }
  .givehero .giveform { margin-top: 0; }
}
.givehero__say > * + * { margin-top: var(--s-6); }
.givehero__plate { margin: 0; }
.givehero__plate img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; box-shadow: var(--lift-photo); }
.figures--give { grid-template-columns: repeat(3, 1fr); gap: var(--s-5); }
@media (max-width: 43.99rem) { .figures--give { grid-template-columns: 1fr; } }
.figures--give .fig__n { font-size: clamp(1.6rem, 1.3rem + 1vw, 2.2rem); }
.givewhy { display: grid; gap: var(--s-6); margin-top: var(--s-7); }
@media (min-width: 40rem) { .givewhy { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
