/* =============================================================================
   FEEED — design revisions
   =============================================================================

   feeed.css is the signed-off mockup, byte for byte identical to
   site/assets/css/feeed.css, and the parity check measures the application
   against it. Anything designed AFTER that sign-off lives here instead, so the
   reference stays a reference and every departure from it is visible in one
   file rather than buried in a diff of six hundred lines.

   Loaded after feeed.css and using its tokens throughout. It adds rules rather
   than overriding them; the one exception is the ground palette below, which is
   a deliberate site-wide change and is documented where it happens.

   ROUNDS
     1 · Registration & Compliance   (client mock, August 2026)
     2 · Our Work                    (client mock, August 2026)
     3 · People behind FEEED         (client mock, August 2026)
   ========================================================================== */

/* --- ground, lightened ----------------------------------------------------- */
/*
 * The mockup's cream (#F2ECDD) reads distinctly tan on a screen, and every one
 * of the client's mocks is set on something much closer to paper. Lifting the
 * three ground tokens brightens the whole site from one place, which is the
 * point: a bright new page sitting beside sixteen tan ones would read as a
 * mistake, not a redesign.
 *
 * Only the grounds move. The greens, golds and inks are untouched, and because
 * every one of them is darker than the ground, lightening it raises the
 * contrast of body copy rather than lowering it — .doccard__text goes from
 * about 5.3:1 to 6.0:1 against what sits behind it.
 *
 * Two moves, not one. The first is lightness — the mockup's ground sits about
 * 8% down from white and the mock's barely 4%. The second, and the one that
 * actually made the site look like a different design, is CHROMA: #F2ECDD is a
 * saturated beige, and the mock's ground is very nearly neutral, warm only
 * enough to keep it off clinical white. Lightening alone left the page still
 * reading as tan, which is what the client kept seeing.
 *
 * The three keep their old relationship to each other: `soft` a shade above the
 * page, `deep` a shade below it, so the layering the mockup designed still
 * works. Revert these three lines and the site is exactly as it was.
 */
:root {
  --cream:      #F6F5F1;
  --cream-soft: #FBFBF8;
  --cream-deep: #E8E6DE;
}

:root {
  /* Radii. The mockup is square-cornered at 2px; the revised cards are
     noticeably rounded, which is the single largest visual change. Named
     rather than repeated so the next page inherits the same softness. */
  --r-card: 12px;
  --r-panel: 18px;

  /* Document accent colours, sampled from the client's mock.
     Deliberately outside the site palette: these six are wayfinding, not
     brand. A compliance officer scanning for the 80G certificate finds it by
     colour before they finish reading the labels, which is the whole reason
     the client asked for icon cards instead of a list.

     Lighter and softer than a first pass at them was — the mock's chips are
     pastel rather than saturated, and matching that is the point. The cost is
     that a white glyph on the amber sits near 2.6:1, under the 3:1 WCAG asks
     of a graphical object. That is a property of gold-and-white and is in the
     mock too. It is survivable here only because the glyph is decoration: the
     document's name is set in deep green directly beneath it and carries every
     piece of information the chip does. */
  --doc-green:  #6E9C55;
  --doc-blue:   #3F72B8;
  --doc-teal:   #2C8880;
  --doc-amber:  #D7A03C;
  --doc-purple: #7A4EAB;
  --doc-red:    #DC6C62;

  --wash-green: rgba(20, 69, 47, .10);

  /* The chip behind an icon. Pale enough to carry a deep-green glyph at full
     strength, whether it sits on cream or on the deep green itself. */
  --sage: #E4EDDF;

  /* The founder panel's ground. Warmer than the page and darker than it, which
     is the relationship the mock draws — a plaque laid on the paper rather than
     a patch of it. Well above the mockup's old #F2ECDD in lightness, so it
     reads as ivory rather than the tan the client kept objecting to. */
  --wash-warm: #F4F1E6;

  /* The script face, used for the two signatures. No web font is fetched for
     it: a signature is a personal mark, the honest version is a scan of the
     real one, and until there is one this is plainly a stand-in set in whatever
     hand the reader's own machine has. */
  --script: 'Segoe Script', 'Bradley Hand', 'Snell Roundhand', 'Brush Script MT', cursive;

  /* Programme accents.
     A programme is recognised by its colour as much as its name, so these six
     are fixed and each programme record names one. Sampled from the client's
     mock, and in the same register as the document chips — bright enough to
     tell apart on a photograph, muted enough not to fight the deep green. */
  --acc-green:  #4A7C46;
  --acc-teal:   #1F8A83;
  --acc-orange: #E1712F;
  --acc-purple: #7A3FA8;
  --acc-blue:   #2E6FB5;
  --acc-gold:   #C08A1E;
}

/* --- breadcrumbs ---------------------------------------------------------- */

.crumbs {
  padding-block: 18px 0;
  font: 400 13px/1.5 var(--body);
  color: var(--ink-soft);
}
.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  list-style: none;
}
.crumbs a {
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.crumbs a:hover { color: var(--green); border-bottom-color: var(--gold); }
.crumbs li[aria-current="page"] { color: var(--ink-mid); font-weight: 500; }
/* The separator is drawn, not typed, so it is never read aloud as "greater
   than" between every step of the trail. */
.crumbs li + li::before {
  content: '';
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 8px;
  border-top: 1.4px solid var(--rule-strong);
  border-right: 1.4px solid var(--rule-strong);
  transform: rotate(45deg) translateY(-1px);
}

/* --- credential hero ------------------------------------------------------ */

.credhero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr) minmax(0, .92fr);
  gap: clamp(24px, 3vw, 52px);
  align-items: center;
  padding-block: clamp(28px, 3.4vw, 48px) clamp(44px, 5vw, 74px);
}
/*
 * The mockup sets every display heading with `text-wrap: balance`, which splits
 * "Registration & Compliance" into two even halves and strands the ampersand at
 * the start of line two. The client's mock breaks it the way ordinary greedy
 * wrapping does — "Registration &" then "Compliance" — so balance is off here.
 */
.credhero h1 { text-wrap: wrap; }

.credhero__rule {
  width: 68px;
  height: 3px;
  margin-top: 26px;
  background: var(--gold);
}
.credhero__lede {
  margin-top: 24px;
  max-width: 42ch;
  font-size: clamp(16px, 1.15vw, 18px);
  line-height: 1.62;
  color: var(--ink-mid);
}
.credhero__actions { margin-top: 32px; display: flex; gap: 12px; flex-wrap: wrap; }
.credhero__actions .btn { border-radius: 4px; }

.cert-art { width: 100%; height: auto; display: block; }
.cert-art__wash      { fill: var(--wash-green); }
.cert-art__dots      { fill: var(--green); opacity: .22; }
.cert-art__shadow    { fill: rgba(20, 69, 47, .10); }
.cert-art__plinth-rim{ fill: none; stroke: var(--cream-deep); stroke-width: 1.5; }
.cert-art__frame     { fill: var(--green); }
.cert-art__keyline   { fill: none; stroke: var(--gold); stroke-width: 1.4; opacity: .7; }
.cert-art__title {
  font: 700 19px var(--body);
  letter-spacing: .06em;
  fill: var(--green);
}
.cert-art__line  { font: 400 11.5px var(--body); fill: var(--ink-soft); }
.cert-art__sig   { font: 500 8px var(--mono); letter-spacing: .12em; fill: var(--ink-soft); }
.cert-art__emblem{ fill: none; stroke: var(--green); stroke-width: 1.5; opacity: .8; }
.cert-art__rules { fill: none; stroke: var(--rule-strong); stroke-width: 1.6; }
.cert-art__ribbon{ fill: var(--green); opacity: .85; }
.cert-art__seal-edge  { fill: none; stroke: var(--gold-bright); stroke-width: 2; opacity: .5; }
.cert-art__seal-inner { fill: none; stroke: #FFF8E4; stroke-width: 1.4; opacity: .55; }
.cert-art__seal-tick  { stroke: #FFFBF0; }
.cert-art__leaf  { fill: var(--green); opacity: .82; }
.cert-art__stem  { fill: none; stroke: var(--green-deep); stroke-width: 2.4; stroke-linecap: round; opacity: .55; }
.cert-art__pot     { fill: #EDE5D3; }
.cert-art__pot-rim { fill: #E1D7C0; }

/* The assurance card. Rounded, hairline-ruled rows, no shadow — it is a panel
   of statements, not a control the reader can press. */
.assure {
  background: var(--cream-soft);
  border: 1px solid var(--rule);
  border-radius: var(--r-panel);
  padding: clamp(10px, 1.4vw, 18px) clamp(18px, 1.9vw, 26px);
}
.assure__row {
  display: grid;
  grid-template-columns: 48px 1fr;
  gap: 16px;
  align-items: start;
  padding-block: clamp(15px, 1.5vw, 20px);
  border-bottom: 1px solid var(--rule);
}
.assure__row:last-child { border-bottom: 0; }
.assure__icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(20, 69, 47, .10);
  color: var(--green);
  display: flex;
  align-items: center;
  justify-content: center;
}
.assure__icon svg { width: 23px; height: 23px; }
.assure__title {
  font: 600 15.5px/1.3 var(--body);
  color: var(--green);
}
.assure__text {
  margin-top: 5px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-mid);
}

@media (max-width: 1180px) {
  .credhero { grid-template-columns: 1fr 1fr; }
  /* The artwork is the least load-bearing of the three, so it takes the full
     width underneath rather than being squeezed to a thumbnail. */
  .credhero__art { grid-column: 1 / -1; order: 3; max-width: 460px; margin-inline: auto; }
}
@media (max-width: 860px) {
  .credhero { grid-template-columns: 1fr; }
  .credhero__art { order: 3; }
}

/* --- centred section rule ------------------------------------------------- */
/* A heading flanked by gold rules. Used where a section is a shelf of equal
   items rather than an argument, so nothing at the left edge to align to. */

.railhead {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 2vw, 26px);
  margin-bottom: clamp(30px, 3.2vw, 46px);
}
.railhead::before,
.railhead::after {
  content: '';
  flex: 1 1 0;
  max-width: 230px;
  height: 1px;
  background: var(--gold);
  opacity: .55;
}
.railhead__text {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font: 600 clamp(14px, 1.3vw, 17px)/1.2 var(--body);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--green);
  text-align: center;
}
.railhead__text svg { width: 22px; height: 22px; color: var(--gold); flex: none; }

/* --- document cards ------------------------------------------------------- */

.doccards {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: clamp(14px, 1.5vw, 22px);
}
.doccard {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: clamp(22px, 2vw, 30px) 16px 0;
  background: var(--white);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.doccard:hover {
  border-color: var(--gold);
  transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(20, 69, 47, .10);
}
.doccard__icon {
  width: 66px;
  height: 66px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  background: var(--doc-green);
}
.doccard__icon svg { width: 32px; height: 32px; }
/* An uploaded mark sits inside the same chip. Contained, not cropped: a logo
   is somebody else's artwork and must not be trimmed to fit a circle. */
.doccard__mark { width: 40px; height: 40px; object-fit: contain; }
.doccard--blue   .doccard__icon { background: var(--doc-blue); }
.doccard--teal   .doccard__icon { background: var(--doc-teal); }
.doccard--amber  .doccard__icon { background: var(--doc-amber); }
.doccard--purple .doccard__icon { background: var(--doc-purple); }
.doccard--red    .doccard__icon { background: var(--doc-red); }

.doccard__title {
  margin-top: 18px;
  font: 600 17px/1.25 var(--body);
  color: var(--green);
}
.doccard__text {
  margin-top: 9px;
  /* The rule below needs air on both sides. Without this the description sits
     hard against it while "Download PDF" has 15px of padding underneath, so the
     line reads as glued to the paragraph rather than dividing two things. */
  margin-bottom: 18px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-mid);
  /* Two lines of description on every card, whether the sentence is short or
     long, so the download links land on one baseline across the row. */
  min-height: 3em;
}
.doccard__get {
  margin-top: auto;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 14px 10px 16px;
  border-top: 1px solid var(--rule);
  /* A real line-height, not 1. Setting it to 1 made the text box shorter than
     the arrow beside it, so centring the two put the word off the icon's
     optical centre — the thing that looked subtly wrong in the row. */
  font: 500 14px/1.35 var(--body);
  white-space: nowrap;
  color: var(--ink);
  text-decoration: none;
  transition: color .18s ease, background .18s ease;
}
.doccard__get svg { width: 16px; height: 16px; flex: none; }
.doccard__get:hover { color: var(--green); background: var(--cream); }
/* A record with no file uploaded yet is inert rather than a download that
   404s — the same rule the mockup's document lists already follow. */
.doccard__get[aria-disabled='true'] { color: var(--ink-soft); pointer-events: none; }
.doccard__get[aria-disabled='true'] svg { opacity: .45; }

@media (max-width: 1180px) { .doccards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 720px)  { .doccards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 460px)  { .doccards { grid-template-columns: 1fr; } }

/* --- trust band ----------------------------------------------------------- */
/*
 * One low band, not three stacked blocks. The mock keeps the whole thing to
 * about the height of the green card, which is what stops it competing with
 * the document shelf above it — so everything here is sized to that ceiling.
 */

.trustband {
  display: grid;
  grid-template-columns: minmax(222px, .74fr) minmax(0, 2.8fr) minmax(186px, .9fr);
  align-items: stretch;
  gap: clamp(16px, 1.8vw, 28px);
  background: var(--cream-soft);
  border: 1px solid var(--rule);
  border-radius: var(--r-panel);
  padding: clamp(12px, 1.2vw, 16px);
}
.trustband__pledge {
  background: var(--green);
  color: var(--on-dark);
  border-radius: var(--r-card);
  padding: clamp(18px, 1.8vw, 24px);
  display: grid;
  grid-template-columns: auto 1fr;
  align-content: center;
  gap: 4px 14px;
}
.trustband__pledge svg { width: 32px; height: 32px; color: var(--gold-bright); }
/*
 * Set in the body face, not the display serif the rest of the site uses for
 * headings. This is a two-line stamp inside a chip, and Fraunces at this size
 * reads as a pull quote — which is what made the block feel like a different
 * design from the one the client drew.
 */
.trustband__pledge-title {
  align-self: center;
  font: 700 clamp(15px, 1.15vw, 17.5px)/1.32 var(--body);
  letter-spacing: .002em;
  color: var(--on-dark);
}
.trustband__pledge-text {
  grid-column: 1 / -1;
  margin-top: 10px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--on-dark-mid);
}

.trustband__stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  /* The row is centred in the band, but the four cells are top-aligned inside
     it. Centring the cells too would drop the three one-line captions below the
     one that wraps, and put four numbers at three different heights. */
  align-content: center;
  align-items: start;
  padding-inline: clamp(8px, 1.1vw, 18px);
  /* Dashed on the outside, hairline between: the dashes mark where the band
     changes register, the hairlines only separate one figure from the next. */
  border-inline: 1px dashed var(--rule-strong);
}
.trustband__stat {
  display: flex;
  align-items: flex-start;
  gap: clamp(7px, .75vw, 9px);
  /* Tight, so "Projects Completed" stays on the one line the mock gives it.
     The four captions are what set this width, not the numbers — every pixel
     spent on the icon or the gutter comes straight out of the caption. */
  padding-inline: clamp(6px, .75vw, 11px);
  border-left: 1px solid var(--rule);
}
.trustband__stat:first-child { border-left: 0; padding-left: 0; }
.trustband__stat > svg {
  width: 24px;
  height: 24px;
  margin-top: 1px;
  color: var(--green);
  opacity: .75;
  flex: none;
}
/* Body face again, for the same reason as the pledge title. The display serif
   belongs to the impact dashboard's figures, which are the trust's headline
   claims; these four are a summary strip and are set to match the mock. */
.trustband__num {
  font: 700 clamp(21px, 1.7vw, 26px)/1.05 var(--body);
  letter-spacing: -.015em;
  color: var(--green);
}
.trustband__label {
  margin-top: 6px;
  font: 600 12px/1.32 var(--body);
  color: var(--ink);
}
.trustband__sub {
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.3;
  color: var(--ink-soft);
}

.trustband__quote {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: clamp(10px, 1.2vw, 16px) clamp(8px, 1vw, 14px);
  overflow: hidden;
}
.trustband__mark {
  flex: none;
  align-self: flex-start;
  margin-top: 2px;
  font-family: var(--display);
  font-size: 40px;
  line-height: .8;
  color: var(--gold);
  opacity: .42;
}
.trustband__quote p {
  position: relative;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-mid);
}
/* A leaf watermark, echoing the plant in the hero. Decorative and low
   contrast; it must never come between the reader and the sentence. */
.trustband__leaf {
  position: absolute;
  right: -6px;
  bottom: -10px;
  width: 64px;
  height: 64px;
  color: var(--green);
  opacity: .07;
  pointer-events: none;
}

@media (max-width: 1280px) {
  .trustband { grid-template-columns: minmax(230px, .9fr) minmax(0, 2fr); }
  .trustband__quote {
    grid-column: 1 / -1;
    border-top: 1px dashed var(--rule-strong);
    padding-top: 16px;
  }
}
@media (max-width: 900px) {
  .trustband { grid-template-columns: 1fr; }
  .trustband__stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 22px;
    border-inline: 0;
    border-top: 1px dashed var(--rule-strong);
    padding: 22px 0 0;
  }
  .trustband__stat:nth-child(odd) { border-left: 0; padding-left: 0; }
}

/* --- verification note ---------------------------------------------------- */

.verified {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px 26px;
  margin-top: clamp(30px, 3.4vw, 48px);
  padding-top: clamp(20px, 2.2vw, 28px);
  border-top: 1px solid var(--rule);
  font-size: 14px;
  color: var(--ink-mid);
}
.verified__item { display: inline-flex; align-items: center; gap: 9px; }
.verified__item svg { width: 17px; height: 17px; color: var(--green); opacity: .8; }
.verified__sep { color: var(--rule-strong); }
.verified__stamp { font: 500 13px/1 var(--body); color: var(--ink); }

@media (max-width: 620px) {
  .verified__sep { display: none; }
  .verified { flex-direction: column; gap: 12px; }
}

/* =============================================================================
   ROUND 2 · Our Work  (client mock, August 2026)
   ========================================================================== */

/* --- utility bar icons ---------------------------------------------------- */
/* The bar itself is the mockup's. Only the two marks in front of the phone
   number and the address are new, and they are what make the strip scan as
   contact details rather than as a sentence. */

.utility a svg { width: 13px; height: 13px; color: var(--gold-bright); flex: none; }

/* --- navigation ----------------------------------------------------------- */
/*
 * Two changes to the mockup's menu: the section you are in is marked with a
 * filled chip rather than only an underline, and the dropdown carries a glyph
 * per item. The glyph is the reason the panel got wider — an icon column that
 * pushes the labels into a ragged second column would be worse than no icons.
 */

.nav__link[aria-current='page'] {
  background: var(--cream-soft);
  border-radius: 8px 8px 0 0;
  box-shadow: inset 0 -2px 0 var(--gold);
}
/* Held open on hover as well, so the chip and the panel below it read as one
   object rather than the panel floating free of its trigger. */
.nav__item:hover .nav__link,
.nav__item:focus-within .nav__link {
  background: var(--cream-soft);
  border-radius: 8px 8px 0 0;
}

.nav__panel {
  min-width: 268px;
  padding: 10px;
  border: 1px solid var(--rule);
  border-radius: 0 var(--r-card) var(--r-card) var(--r-card);
  box-shadow: 0 22px 48px rgba(20, 69, 47, .16);
}
.nav__panel a {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 14.5px;
}
.nav__panel a:hover { background: var(--cream-soft); color: var(--green); }
.nav__panel a svg { width: 19px; height: 19px; color: var(--green); opacity: .62; flex: none; }
.nav__panel a:hover svg { opacity: 1; color: var(--gold); }
/* The overview link — the one pointing at the section's own page — is ruled off
   from the specific pages under it. Derived from the address rather than a flag
   somebody has to remember to tick. */
.nav__panel .nav__overview {
  margin-bottom: 6px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
  border-radius: 8px 8px 0 0;
}

/* --- hero with points ----------------------------------------------------- */

.pointhero {
  display: grid;
  /* Weighted to the photograph, as the mock is. The words need about 42% to
     keep the heading on two lines; everything past that belongs to the
     picture, which is carrying the card as well as itself. */
  grid-template-columns: minmax(0, .84fr) minmax(0, 1.16fr);
  gap: clamp(28px, 4vw, 68px);
  align-items: center;
  padding-block: clamp(30px, 3.6vw, 52px) clamp(40px, 4.6vw, 70px);
}
/*
 * Smaller than `display-l`'s own clamp. At 58px "Focused programmes. Lasting
 * change." breaks into three lines in a column this width, and the mock sets it
 * as two — the second of which is the half that carries the promise.
 */
.pointhero h1 { font-size: clamp(30px, 3.3vw, 46px); }

.pointhero__lede {
  margin-top: 22px;
  max-width: 46ch;
  font-size: clamp(16px, 1.15vw, 18px);
  line-height: 1.62;
  color: var(--ink-mid);
}
.pointhero__actions { margin-top: 30px; display: flex; gap: 12px; flex-wrap: wrap; }
.pointhero__actions .btn { border-radius: 4px; }

.pointhero__stage { position: relative; }
.pointhero__shot {
  border-radius: var(--r-panel);
  overflow: hidden;
  background: var(--cream-deep);
  aspect-ratio: 16 / 11;
}
.pointhero__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }

/*
 * The points card overlaps the photograph's lower-right corner. Absolute only
 * where there is room for it to sit over the image without covering a face —
 * below 1080px it drops underneath instead, because a card floating over a
 * narrow photograph hides the picture it is meant to annotate.
 */
.pointhero__points {
  margin-top: 16px;
  background: var(--green);
  color: var(--on-dark);
  border-radius: var(--r-card);
  padding: clamp(16px, 1.6vw, 22px) clamp(18px, 1.8vw, 26px);
  display: flex;
  flex-direction: column;
  gap: clamp(11px, 1.1vw, 15px);
}
.pointhero__point { display: flex; align-items: center; gap: 13px; }
/*
 * A solid pale disc, not a translucent wash of the card's own ground.
 *
 * The wash let the deep green through, so the glyph inside had to be gold to
 * show up at all — four dim smudges where the mock has four bright marks. A
 * light chip carrying a full-strength green glyph is legible at this size and
 * is what the mock draws.
 */
.pointhero__point span {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--sage);
  color: var(--green);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.pointhero__point span svg { width: 18px; height: 18px; }
.pointhero__point p { font: 500 14.5px/1.35 var(--body); color: var(--on-dark); }

@media (min-width: 1081px) {
  /*
   * The card straddles the photograph's bottom-right corner rather than sitting
   * wholly inside it. Tucked in, it ate a rectangle out of the middle of the
   * picture; hung off the corner, about a third of it lands on the page and the
   * photograph keeps that much more of itself. It still reads as pinned to the
   * image rather than floating loose, because two of its edges are still over
   * it.
   *
   * The overhangs are bounded by what there is room for: the right one has to
   * stay inside `--gut`, which is 43px at the 1081px breakpoint where this rule
   * starts, and the bottom one inside the section's own bottom padding.
   */
  .pointhero__points {
    position: absolute;
    right: calc(-1 * clamp(10px, 1.1vw, 18px));
    bottom: calc(-1 * clamp(14px, 1.5vw, 26px));
    margin-top: 0;
    max-width: 292px;
    box-shadow: 0 22px 48px rgba(11, 36, 24, .3);
  }
}
@media (max-width: 900px) {
  .pointhero { grid-template-columns: 1fr; }
}

/* --- centred head with dashes --------------------------------------------- */
/* The "Areas We Work In" heading. A short gold dash each side rather than the
   full rules the document shelf uses — this section has a standfirst under it,
   and long rules over three stacked lines reads as a banner. */

.dashhead { text-align: center; margin-bottom: clamp(26px, 3vw, 40px); }
.dashhead .label { display: block; margin-bottom: 12px; }
.dashhead__line {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
}
.dashhead__line::before,
.dashhead__line::after {
  content: '';
  width: clamp(20px, 3vw, 38px);
  height: 2px;
  background: var(--gold);
  flex: none;
}
.dashhead p {
  margin-top: 14px;
  margin-inline: auto;
  max-width: 62ch;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--ink-mid);
}

/* --- programme cards ------------------------------------------------------ */

.progcards {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: clamp(14px, 1.5vw, 22px);
}
.progcard {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  text-decoration: none;
  color: inherit;
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.progcard:hover {
  border-color: var(--accent, var(--gold));
  transform: translateY(-3px);
  box-shadow: 0 14px 32px rgba(20, 69, 47, .12);
}
/* The clip lives here, not on the card: the badge hangs off the card's corner
   and `overflow: hidden` one level up would slice it in half. */
.progcard__shot {
  aspect-ratio: 3 / 2;
  background: var(--cream-deep);
  border-radius: calc(var(--r-card) - 1px) calc(var(--r-card) - 1px) 0 0;
  overflow: hidden;
}
.progcard__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .5s cubic-bezier(.22, .61, .36, 1);
}
.progcard:hover .progcard__shot img { transform: scale(1.05); }
/*
 * The badge straddles the photograph's top-left corner. A ring of the card's
 * own background separates it from whatever is behind it, so it stays legible
 * over a bright sky and a dark interior alike.
 */
.progcard__badge {
  position: absolute;
  z-index: 2;
  /* Over the top edge but inside the left one. Hanging off both corners looked
     like the badge had come loose from the card rather than been pinned to it. */
  top: -18px;
  left: 14px;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent, var(--green));
  color: #fff;
  border: 3px solid var(--white);
}
.progcard__badge svg { width: 22px; height: 22px; }
/*
 * The brand green is treated as a tint rather than a solid. A solid deep-green
 * disc reads as the site's own furniture — a close button, a logo — where the
 * other five read as a category colour. Tinting it keeps Education and
 * Environment recognisable as FEEED's own without that confusion.
 */
.progcard[data-accent='green'] .progcard__badge {
  background: var(--sage);
  color: var(--acc-green);
}

.progcard__body {
  padding: clamp(16px, 1.5vw, 20px) clamp(14px, 1.3vw, 18px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
}
.progcard__title { font: 600 16.5px/1.25 var(--body); color: var(--green); }
.progcard__text { font-size: 13.5px; line-height: 1.52; color: var(--ink-mid); }
.progcard__more {
  margin-top: auto;
  padding-top: 12px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font: 600 13.5px/1 var(--body);
  color: var(--accent, var(--green));
}
.progcard__more svg { width: 14px; height: 14px; transition: transform .2s ease; }
.progcard:hover .progcard__more svg { transform: translateX(3px); }

@media (max-width: 1180px) { .progcards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 760px)  { .progcards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 460px)  { .progcards { grid-template-columns: 1fr; } }

/* --- impact banner -------------------------------------------------------- */

.impactband {
  display: grid;
  grid-template-columns: minmax(252px, .92fr) minmax(0, 2.55fr) auto;
  align-items: center;
  gap: clamp(20px, 2.4vw, 40px);
  background: #EDF2E8;
  border-radius: var(--r-panel);
  padding: clamp(20px, 2.2vw, 30px) clamp(22px, 2.4vw, 34px);
}
.impactband__lead { display: flex; align-items: center; gap: 16px; }
.impactband__lead > span {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(20, 69, 47, .10);
  color: var(--green);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.impactband__lead > span svg { width: 24px; height: 24px; }
.impactband__title {
  font-family: var(--display);
  font-weight: 500;
  /* Smaller than it first looked. The mock sets this at about 19px over two
     lines; at 24px the same sentence needs four in the space beside the icon,
     and the band stops being one low strip. */
  font-size: clamp(16.5px, 1.3vw, 19px);
  line-height: 1.28;
  color: var(--green);
  /* Not balanced. Balancing splits this sentence into short even lines where
     greedy wrapping gives the two the mock has. */
  text-wrap: wrap;
}

.impactband__figures {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 24px);
}
.impactband__figure { display: flex; align-items: center; gap: 10px; }
.impactband__figure > svg { width: 28px; height: 28px; color: var(--green); opacity: .7; flex: none; }
.impactband__num {
  font: 700 clamp(18px, 1.5vw, 22px)/1.1 var(--body);
  letter-spacing: -.015em;
  color: var(--green);
}
.impactband__cap {
  margin-top: 3px;
  font-size: 12.5px;
  line-height: 1.3;
  color: var(--ink-mid);
  /* One line each, as the mock has them. A caption that wraps puts the four
     numbers on four different baselines. */
  white-space: nowrap;
}
.impactband .btn { white-space: nowrap; border-radius: 4px; }

@media (max-width: 1280px) {
  .impactband { grid-template-columns: 1fr auto; }
  .impactband__figures { grid-column: 1 / -1; order: 3; }
}
@media (max-width: 860px) {
  .impactband { grid-template-columns: 1fr; text-align: left; }
  .impactband__figures { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 20px; }
  .impactband .btn { justify-self: start; }
}

/* --- bands that continue the section above them --------------------------- */
/*
 * The impact band and the trust band are summaries of what has just been said,
 * not new subjects. Setting them flush zeroes their own top padding, but the
 * section above still pays a full section's worth underneath itself — about
 * 100px — and the band ends up marooned in the middle of it.
 *
 * So the section immediately before one gives that padding up. Written with
 * `:has()` rather than a modifier class on the section above, because the
 * spacing is a fact about the pair, and a class would have to be set by hand on
 * whichever section happened to precede the band today.
 */
.section:has(+ .section .impactband),
.section:has(+ .section .trustband) {
  padding-bottom: clamp(28px, 3vw, 44px);
}

/* =============================================================================
   ROUND 3 — People behind FEEED
   ========================================================================== */

/* --- a fourth spacing step ------------------------------------------------ */
/*
 * The mockup's rhythm is generous: `.section` is 56–104px of air top and
 * bottom, and `.section--tight` still 38–62px, which reads as one argument
 * followed by another. Every page in the client's redesign stacks panels
 * instead — a founder card, a shelf of people, a band of values — and sets them
 * about 30px apart, so they read as one page rather than five chapters.
 *
 * A step between `tight` and `flush` rather than a special case per section:
 * the next mock will want it too, and it belongs in the appearance control
 * where an editor can see it.
 */
.section--snug { padding-block: clamp(16px, 1.7vw, 24px); }

/* --- hero with figures ---------------------------------------------------- */

.figurehero {
  display: grid;
  /* The mock gives the words about a third of the measure and the photograph
     the rest. It matters: at 44% the headline fits on one line and the mock
     sets it on two. */
  grid-template-columns: minmax(0, .68fr) minmax(0, 1.32fr);
  gap: clamp(28px, 3.4vw, 54px);
  align-items: center;
  padding-block: clamp(18px, 2vw, 28px) 0;
}
.figurehero__words { padding-block: clamp(10px, 2vw, 34px); }

/*
 * Heavier and tighter than `display-l`. The mock sets this headline at a weight
 * the rest of the site does not use — it is the one line on the page that has
 * to hold its own against a photograph twice its size.
 */
.figurehero__title {
  font-size: clamp(33px, 3.8vw, 55px);
  font-weight: 600;
  line-height: 1.02;
}

.figurehero__rule {
  width: 60px;
  height: 3px;
  margin-top: 14px;
  background: var(--gold);
}
.figurehero__lede {
  margin-top: 24px;
  max-width: 42ch;
  font-size: clamp(16px, 1.15vw, 18px);
  line-height: 1.62;
  color: var(--ink-mid);
}

/*
 * The photograph and the card stand side by side, not one on top of the other:
 * in the mock the card's left edge meets the picture's right edge and laps just
 * over it. Two columns of one row rather than an absolutely placed card, so the
 * picture's height sets the row and the card can never overhang it.
 */
.figurehero__stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(232px, 20.5vw, 292px);
  align-items: end;
}

/*
 * The arch.
 *
 * The mock rounds the photograph's two left corners so far that the left edge
 * becomes a single curve, and squares off the right where the card stands. It
 * is the strongest shape on the page and the reason the hero does not read as
 * two rectangles side by side. The radius is capped in pixels rather than set
 * as a percentage so the curve keeps the same character as the picture grows.
 */
.figurehero__shot {
  grid-area: 1 / 1;
  /*
   * An ellipse, not a circle. A single radius large enough to reach the middle
   * of the left edge bulges the corners out into a lozenge; giving the vertical
   * radius half the height and the horizontal one about a fifth of the width
   * draws the long shallow arc the mock has.
   */
  border-radius: clamp(56px, 10vw, 150px) var(--r-panel) var(--r-panel)
    clamp(56px, 10vw, 150px) / 50% var(--r-panel) var(--r-panel) 50%;
  overflow: hidden;
  background: var(--cream-deep);
  aspect-ratio: 3 / 2.15;
}
.figurehero__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }

/*
 * The card standing on the photograph's right edge.
 *
 * Below 1080px it drops underneath the picture instead. A card this tall
 * floating over a narrow photograph covers the people it is vouching for, and
 * on this page those people are the subject.
 */
.figurehero__badge {
  margin-top: 16px;
  background: var(--green);
  color: var(--on-dark);
  border-radius: var(--r-card);
  padding: clamp(18px, 1.8vw, 24px) clamp(18px, 1.8vw, 24px) clamp(16px, 1.6vw, 22px);
}
.figurehero__badge-head {
  display: flex;
  align-items: center;
  gap: 11px;
  padding-bottom: 13px;
  border-bottom: 1px solid rgba(217, 162, 39, .5);
  font: 600 17px/1.2 var(--body);
  color: var(--on-dark);
}
.figurehero__badge-head svg { width: 22px; height: 22px; color: var(--gold-bright); flex: none; }

.figurehero__badge-list {
  margin-top: 15px;
  display: flex;
  flex-direction: column;
  gap: 11px;
}
.figurehero__badge-list li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font: 400 14.5px/1.4 var(--body);
  color: var(--on-dark);
}
.figurehero__badge-list li svg {
  width: 18px;
  height: 18px;
  flex: none;
  margin-top: 1px;
  color: var(--on-dark);
  opacity: .8;
}
.figurehero__badge p {
  margin-top: 14px;
  font: 400 13.5px/1.55 var(--body);
  color: var(--on-dark-mid);
}

.figurehero__badge-sign {
  margin-top: 16px;
  padding-top: 15px;
  border-top: 1px solid rgba(217, 162, 39, .5);
  text-align: center;
}
.figurehero__badge-sign img { margin: 0 auto; max-height: 46px; width: auto; object-fit: contain; }
.figurehero__badge-sign .handsig { color: var(--on-dark); font-size: 22px; }
.figurehero__badge-role {
  margin-top: 6px;
  font: 500 12.5px/1.3 var(--body);
  color: var(--on-dark-mid);
}

@media (min-width: 1081px) {
  .figurehero__badge {
    grid-area: 1 / 2;
    /* Lapping over the picture's edge by a few pixels. Flush would leave a
       hairline of background between the two at some widths, and a gap there
       reads as a mistake rather than as two things placed apart. */
    margin: 0 0 0 -14px;
    box-shadow: 0 22px 48px rgba(11, 36, 24, .32);
  }
}
/* Under the picture, full width, on anything narrower. A card this tall over a
   narrow photograph covers the people it is vouching for. */
@media (max-width: 1080px) {
  .figurehero__stage { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  .figurehero { grid-template-columns: 1fr; }
  .figurehero__shot {
    border-radius: clamp(40px, 9vw, 110px) var(--r-panel) var(--r-panel)
      clamp(40px, 9vw, 110px) / 50% var(--r-panel) var(--r-panel) 50%;
  }
}

/* --- the band of figures under the hero ----------------------------------- */
/*
 * A band of its own across the full measure, sitting directly under the hero.
 * Four counts about the organisation, each an icon with its number beside it —
 * beside, not above, because the caption then has the width to break where it
 * was written to break rather than wherever it runs out of room.
 */

.figureband {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  background: var(--wash-warm);
  border-radius: var(--r-panel);
  padding: clamp(20px, 2.2vw, 30px) clamp(14px, 1.6vw, 24px);
  margin-bottom: clamp(6px, 1vw, 16px);
}
.figureband__figure {
  display: flex;
  align-items: center;
  gap: clamp(12px, 1.3vw, 18px);
  padding-inline: clamp(12px, 1.8vw, 30px);
  border-left: 1px solid var(--rule);
}
.figureband__figure:first-child { border-left: 0; }
.figureband__figure > svg {
  width: clamp(34px, 3vw, 44px);
  height: clamp(34px, 3vw, 44px);
  color: var(--green);
  opacity: .85;
  flex: none;
}
.figureband__num {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(24px, 2.3vw, 33px);
  line-height: 1;
  color: var(--green);
  font-variation-settings: 'SOFT' 0, 'WONK' 0;
}
.figureband__cap {
  margin-top: 7px;
  font: 400 13.5px/1.4 var(--body);
  color: var(--ink-mid);
  /* Line breaks typed into the caption are kept. The client reads these mocks
     line by line, and "Years of / Collective Experience" is a break they chose;
     leaving it to the wrapping algorithm makes it a break that moves whenever
     the column does. */
  white-space: pre-line;
}

@media (max-width: 860px) {
  .figureband { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 26px; }
  .figureband__figure:nth-child(odd) { border-left: 0; }
}
@media (max-width: 460px) {
  .figureband { grid-template-columns: 1fr; }
  .figureband__figure { border-left: 0; }
}

/* --- person profile ------------------------------------------------------- */

.profile {
  display: grid;
  grid-template-columns: minmax(0, .62fr) minmax(0, 1.3fr) minmax(0, .82fr);
  gap: clamp(24px, 3vw, 48px);
  align-items: center;
  background: var(--wash-warm);
  border-radius: var(--r-panel);
  padding: clamp(26px, 3vw, 44px) clamp(24px, 2.8vw, 40px);
}

.profile__portrait { position: relative; text-align: center; }
.profile__frame {
  display: block;
  position: relative;
  z-index: 1;
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--cream-deep);
  aspect-ratio: 4 / 4.6;
}
.profile__frame img { width: 100%; height: 100%; object-fit: cover; display: block; }

/*
 * Two blocks of dots behind the portrait's corners, drawn as a repeating
 * gradient rather than as markup. Decoration only, and the reason the portrait
 * sits on its own z-index above them.
 */
.profile__dots {
  position: absolute;
  z-index: 0;
  width: 84px;
  height: 84px;
  background-image: radial-gradient(var(--gold) 1.6px, transparent 1.6px);
  background-size: 12px 12px;
  opacity: .5;
}
.profile__dots--tr { top: -18px; right: -18px; }
.profile__dots--bl { bottom: 42px; left: -20px; }

/*
 * The signature.
 *
 * A scan is what belongs here. Until one is uploaded the name is set in
 * whatever script face the reader's machine has — Segoe Script on Windows,
 * Snell Roundhand on a Mac — and falls back to italic serif on anything else.
 * That is a stand-in and looks like one; it is not trying to be a hand.
 */
.profile__signature {
  display: block;
  margin-top: 16px;
  font-size: 20px;
  color: var(--ink-mid);
}
.profile__signature-scan {
  margin: 14px auto 0;
  max-height: 56px;
  width: auto;
  object-fit: contain;
}

.profile__words .label { display: block; }
.profile__name { margin-top: 12px; font-size: clamp(25px, 2.3vw, 34px); }
.profile__credit {
  margin-top: 10px;
  font: 500 13.5px/1.5 var(--body);
  letter-spacing: .01em;
  color: var(--ink-soft);
}
.profile__text {
  margin-top: 16px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink-mid);
  max-width: 52ch;
}
.profile__action { margin-top: 24px; border-radius: 4px; }

/* The expertise card. White on the warm panel, so it reads as a separate note
   pinned to it rather than a ruled-off part of the same sheet. */
.profile__card {
  background: var(--white);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  padding: clamp(20px, 2vw, 26px) clamp(18px, 1.8vw, 24px);
}
.profile__card-head {
  font: 500 11px/1 var(--mono);
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--green);
  padding-bottom: 16px;
  border-bottom: 1px solid var(--rule);
}
.profile__card ul { margin-top: 16px; display: flex; flex-direction: column; gap: 13px; }
.profile__card li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--ink-mid);
}
.profile__card li svg { width: 17px; height: 17px; color: var(--green); flex: none; margin-top: 1px; }

@media (max-width: 1180px) {
  .profile { grid-template-columns: minmax(0, .7fr) minmax(0, 1.3fr); }
  .profile__card { grid-column: 1 / -1; }
}
@media (max-width: 720px) {
  .profile { grid-template-columns: 1fr; }
  .profile__portrait { max-width: 260px; margin-inline: auto; }
  .profile__dots { display: none; }
}

/* A name set as a signature. See --script for why it is not a web font. */
.handsig {
  display: block;
  font-family: var(--script);
  font-style: italic;
  line-height: 1.2;
}

/* --- centred head for a shelf --------------------------------------------- */
/* `.railhead` on its own is the rules and the wording. This adds the line that
   sits under them, and closes the gap between the two so they read as one head
   rather than a heading and a stray sentence. */

.shelfhead { margin-bottom: clamp(26px, 3vw, 40px); }
.shelfhead .railhead { margin-bottom: 10px; }
.shelfhead p {
  margin-inline: auto;
  max-width: 62ch;
  text-align: center;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-mid);
}
.railhead--ondark::before,
.railhead--ondark::after { background: var(--gold-bright); opacity: .7; }
.railhead--ondark .railhead__text { color: var(--on-dark); }
.shelfhead--ondark p { color: var(--on-dark-mid); }

/* --- the sliding shelf ---------------------------------------------------- */
/*
 * One shelf, three uses: the team, the projects and the funders' logos. They
 * differ only in how many cards fit a view, which is the modifier on the track.
 *
 * The track scrolls natively. The arrows and the dots arrive `hidden` and the
 * script reveals them, so with no JavaScript this is still a strip a reader can
 * swipe rather than a row of dead controls. The track is padded a little top
 * and bottom so a card's hover lift is not clipped by the scroller.
 */

.shelf { position: relative; }

.shelf__track {
  display: grid;
  grid-auto-flow: column;
  gap: var(--shelf-gap, clamp(12px, 1.4vw, 20px));
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding-block: 6px;
  /* The scrollbar is furniture the design does not draw; the arrows, the dots
     and the drag are the affordance. */
  scrollbar-width: none;
}
.shelf__track::-webkit-scrollbar { display: none; }
.shelf__track > * { scroll-snap-align: start; }
@media (prefers-reduced-motion: reduce) {
  .shelf__track { scroll-behavior: auto; }
}

/* How many to a view. `--per` is only here to keep the sum readable. */
.shelf--people  .shelf__track { --per: 5; }
.shelf--projects .shelf__track { --per: 4; }
.shelf--logos   .shelf__track { --per: 6; --shelf-gap: clamp(10px, 1.1vw, 16px); }
.shelf__track {
  grid-auto-columns: calc(
    (100% - (var(--per) - 1) * var(--shelf-gap, clamp(12px, 1.4vw, 20px))) / var(--per)
  );
}

/*
 * Hidden until the script has measured the track and found something to scroll
 * to, which it says by marking the shelf live. Done here rather than with the
 * `hidden` attribute because the script runs before React hydrates the page,
 * and an attribute React rendered but no longer finds costs it the whole
 * subtree — see the note on Shelf.tsx.
 */
.shelf__arrow,
.shelf__dots { display: none; }
.shelf[data-rail-live] .shelf__arrow { display: flex; }
.shelf[data-rail-live] .shelf__dots { display: flex; }
/* Too many pages for dots to be aimed at — the script says so. */
.shelf[data-rail-nodots] .shelf__dots { display: none; }

.shelf__arrow {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  z-index: 2;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background .18s ease, opacity .18s ease, border-color .18s ease;
}
/* Two treatments, both from the mocks: filled green where the shelf sits on the
   page's own ground and has to be found, outlined white where it sits beside
   white cards and would shout. */
.shelf__arrow--green {
  border: 0;
  background: var(--green);
  color: var(--on-dark);
  box-shadow: 0 6px 16px rgba(11, 36, 24, .22);
}
.shelf__arrow--green:hover { background: var(--green-deep); }
.shelf__arrow--line {
  border: 1px solid var(--rule);
  background: var(--white);
  color: var(--green);
  box-shadow: 0 4px 14px rgba(20, 69, 47, .1);
}
.shelf__arrow--line:hover { border-color: var(--rule-strong); background: var(--cream-soft); }
/* At either end there is nothing further to show. Dimmed rather than removed,
   so the row does not shift as it is scrolled. */
.shelf__arrow[disabled] { opacity: .3; cursor: default; }
/* Clear of the cards, in the page gutter, which is where the mocks put them.
   The gutter is clamp(20px, 4vw, 60px), so this never pushes them off-screen. */
.shelf__arrow--prev { left: clamp(-46px, -3.2vw, -20px); }
.shelf__arrow--next { right: clamp(-46px, -3.2vw, -20px); }

/* Pages, not cards: one dot per viewful. Twenty-two logos would otherwise be
   twenty-two dots, which is a ruler rather than a control. */
.shelf__dots {
  margin-top: clamp(14px, 1.6vw, 22px);
  justify-content: center;
  gap: 8px;
}
.shelf__dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--rule-strong);
  cursor: pointer;
  transition: background .18s ease, width .18s ease;
}
.shelf__dot[aria-current='true'] { background: var(--green); width: 20px; border-radius: 4px; }

.shelf__more { margin-top: clamp(22px, 2.4vw, 32px); text-align: center; }
.shelf__more .btn { border-radius: 4px; }

@media (max-width: 1180px) {
  .shelf--people .shelf__track { --per: 4; }
  .shelf--projects .shelf__track { --per: 3; }
  .shelf--logos .shelf__track { --per: 5; }
}
@media (max-width: 900px) {
  .shelf--people .shelf__track { --per: 3; }
  .shelf--projects .shelf__track { --per: 2; }
  .shelf--logos .shelf__track { --per: 4; }
  .shelf__arrow--prev { left: 0; }
  .shelf__arrow--next { right: 0; }
}
@media (max-width: 620px) {
  .shelf--people .shelf__track { --per: 2; }
  .shelf--logos .shelf__track { --per: 3; }
  /* No arrows on a phone. There is no room for one beside a card, so it sits on
     top of the card's own words, and the thing it does — move the shelf — is
     what a finger already does. The cut-off card at the edge says the rest is
     there. */
  .shelf[data-rail-live] .shelf__arrow { display: none; }
}
@media (max-width: 460px) {
  .shelf--people .shelf__track { --per: 1.28; }
  .shelf--projects .shelf__track { --per: 1.15; }
  .shelf--logos .shelf__track { --per: 2; }
}

/* --- people cards --------------------------------------------------------- */

.peoplecard {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 4px;
  background: var(--white);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  padding: clamp(18px, 1.8vw, 24px) clamp(12px, 1.2vw, 16px) clamp(14px, 1.4vw, 18px);
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.peoplecard:hover {
  border-color: var(--rule-strong);
  transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(20, 69, 47, .1);
}
.peoplecard__shot {
  width: clamp(72px, 6vw, 88px);
  height: clamp(72px, 6vw, 88px);
  margin-bottom: 14px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--wash-green);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.peoplecard__shot img { width: 100%; height: 100%; object-fit: cover; }
.peoplecard__name { font: 600 14.5px/1.35 var(--body); color: var(--green); }
.peoplecard__role { font-size: 12.5px; line-height: 1.4; color: var(--ink-soft); }
.peoplecard__in {
  margin-top: 10px;
  color: #0A66C2;
  display: inline-flex;
  border-radius: 4px;
  transition: opacity .18s ease;
}
.peoplecard__in:hover { opacity: .75; }

/* Initials, where no portrait has been supplied. Deliberately not a silhouette
   — see the note on PersonShot. */
.shot__monogram {
  font: 600 clamp(20px, 1.8vw, 26px)/1 var(--body);
  letter-spacing: .04em;
  color: var(--green);
  opacity: .55;
}

/* --- people rows ---------------------------------------------------------- */

.peoplerows {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(12px, 1.4vw, 20px);
}
.peoplerow {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--white);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  padding: clamp(12px, 1.2vw, 16px);
}
.peoplerow__shot {
  width: 54px;
  height: 54px;
  border-radius: 9px;
  overflow: hidden;
  background: var(--wash-green);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.peoplerow__shot img { width: 100%; height: 100%; object-fit: cover; }
.peoplerow__shot .shot__monogram { font-size: 17px; }
.peoplerow__name { font: 600 14px/1.35 var(--body); color: var(--green); }
.peoplerow__role { margin-top: 3px; font-size: 12.5px; line-height: 1.4; color: var(--ink-soft); }

@media (max-width: 1080px) { .peoplerows { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .peoplerows { grid-template-columns: 1fr; } }

/* --- values band ---------------------------------------------------------- */
/* Inset with rounded corners rather than run to the page edges: at full bleed
   a green this deep reads as the start of a new chapter, and these five lines
   are a note the page is carrying, not a change of subject. */

.valuesband {
  background: var(--green);
  color: var(--on-dark);
  border-radius: var(--r-panel);
  padding: clamp(28px, 3.2vw, 44px) clamp(20px, 2.4vw, 34px) clamp(30px, 3.4vw, 46px);
}
.valuesband .railhead { margin-bottom: clamp(24px, 2.8vw, 36px); }
.valuesband__grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
}
.valuesband__value {
  padding-inline: clamp(12px, 1.6vw, 24px);
  border-left: 1px solid var(--on-dark-rule);
}
.valuesband__value:first-child { border-left: 0; }
.valuesband__value > svg { width: 30px; height: 30px; color: var(--gold-bright); }
.valuesband__title {
  margin-top: 14px;
  font: 600 15.5px/1.3 var(--body);
  color: var(--on-dark);
}
.valuesband__value p {
  margin-top: 8px;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--on-dark-mid);
}

@media (max-width: 1000px) {
  .valuesband__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 30px; }
  .valuesband__value:nth-child(3n + 1) { border-left: 0; }
}
@media (max-width: 620px) {
  .valuesband__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .valuesband__value:nth-child(3n + 1) { border-left: 1px solid var(--on-dark-rule); }
  .valuesband__value:nth-child(odd) { border-left: 0; }
}

/* --- invitation panel ----------------------------------------------------- */

.invite {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(18px, 2.2vw, 32px);
  background: #EDF2E8;
  border-radius: var(--r-panel);
  padding: clamp(20px, 2.2vw, 30px) clamp(22px, 2.4vw, 34px);
}
.invite__mark {
  width: 58px;
  height: 58px;
  border-radius: 14px;
  background: rgba(20, 69, 47, .1);
  color: var(--green);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.invite__mark svg { width: 28px; height: 28px; }
.invite__title {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(20px, 1.8vw, 26px);
  line-height: 1.22;
  color: var(--green);
  letter-spacing: -.012em;
}
.invite__words p { margin-top: 8px; font-size: 15px; line-height: 1.55; color: var(--ink-mid); }
.invite__actions { display: flex; gap: 12px; flex-wrap: wrap; }
.invite__actions .btn { border-radius: 4px; white-space: nowrap; }
/* The outlined button sits on a tinted ground here, not on the page's own, so
   it needs a fill of its own to keep its edges. */
.invite__actions .btn--line { background: var(--white); }

@media (max-width: 1000px) {
  .invite { grid-template-columns: auto minmax(0, 1fr); }
  .invite__actions { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
  .invite { grid-template-columns: 1fr; }
}

/* =============================================================================
   ROUND 4 — the home page's shelves
   ========================================================================== */

/* --- a heading with a button beside it ------------------------------------ */
/* The mockup's own `.head` puts a text link at the right and aligns both to
   their baselines. This one carries a button, and a button aligned to a
   baseline sits low against a two-line heading — so they are centred against
   each other instead. */

.shelftop {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
  margin-bottom: clamp(24px, 2.8vw, 38px);
}
.shelftop .label { display: block; }
.shelftop .btn { border-radius: 4px; }

/* --- a centred heading ---------------------------------------------------- */
/* No rules at the sides, unlike `.railhead`. The section under this one is a
   wall of logos with nothing to say for itself, and rules flanking the words
   would make the heading compete with it. */

.midhead { text-align: center; margin-bottom: clamp(24px, 2.8vw, 38px); }
.midhead .label { display: block; }
.midhead p {
  margin: 14px auto 0;
  max-width: 68ch;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-mid);
}

/* --- project cards -------------------------------------------------------- */

.projcard {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--white);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
a.projcard:hover {
  border-color: var(--accent, var(--rule-strong));
  transform: translateY(-3px);
  box-shadow: 0 14px 32px rgba(20, 69, 47, .12);
}
.projcard__shot {
  position: relative;
  display: block;
  aspect-ratio: 3 / 2;
  background: var(--cream-deep);
}
.projcard__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .5s cubic-bezier(.22, .61, .36, 1);
}
a.projcard:hover .projcard__shot img { transform: scale(1.05); }

/*
 * The cause-area chip takes its colour from the programme record, so a project
 * is the same colour here, on its programme's page and in the menu. Set in the
 * card's own accent variable by the component.
 */
.projcard__chip {
  position: absolute;
  top: 12px;
  left: 12px;
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--accent, var(--green));
  color: #fff;
  font: 600 11.5px/1 var(--body);
  letter-spacing: .01em;
  /* A programme with a long name — "Women and Child Safety" — must not run the
     width of the photograph. */
  max-width: calc(100% - 24px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.projcard__body {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: clamp(14px, 1.4vw, 18px) clamp(13px, 1.3vw, 17px) clamp(15px, 1.5vw, 19px);
  flex: 1;
}
.projcard__title { font: 600 15px/1.3 var(--body); color: var(--green); }
.projcard__where {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--ink-soft);
}
.projcard__where svg { width: 14px; height: 14px; flex: none; opacity: .8; }
.projcard__text { font-size: 13.5px; line-height: 1.5; color: var(--ink-mid); }
/* Pushed to the foot of the card, so the funder's name sits on one line across
   the shelf however long the sentence above it runs. */
.projcard__partner {
  margin-top: auto;
  padding-top: 12px;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--ink-soft);
}
.projcard__partner b { font-weight: 600; color: var(--ink); }

/* --- logo cards ----------------------------------------------------------- */

.logocard {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--white);
  border: 1px solid var(--rule);
  border-radius: var(--r-card);
  padding: clamp(16px, 1.8vw, 26px) clamp(12px, 1.4vw, 20px);
  min-height: clamp(88px, 8vw, 112px);
  transition: border-color .2s ease, box-shadow .2s ease;
}
.logocard:hover { border-color: var(--rule-strong); box-shadow: 0 10px 24px rgba(20, 69, 47, .08); }
/*
 * Contained, never cropped: these are other people's trademarks and the shape
 * of one is not ours to trim. The cap on both axes is what keeps a tall logo
 * from making its card taller than the rest of the row — and it is set as high
 * as the card allows, because capping height alone leaves a square mark like
 * Global Japan's reading half the size of a wide one like Hyundai's beside it.
 */
.logocard img {
  max-height: clamp(42px, 4vw, 58px);
  width: auto;
  max-width: 100%;
  object-fit: contain;
}

/* --- reasons beside a claim ----------------------------------------------- */

/* The mock's "Why partner with FEEED?" block: the argument on the left, the
   six reasons for it on the right.

   The reasons are one panel with hairlines through it, not six cards. Six
   bordered cards would read as six things to choose between; this is one case
   made in six parts. `.valuesband` does the same on green — the difference is
   only the ground. */

.reasons {
  display: grid;
  grid-template-columns: minmax(0, 27%) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 68px);
  align-items: start;
}

.reasons__rule {
  width: 60px;
  height: 3px;
  margin-top: 14px;
  background: var(--gold);
}
.reasons__title {
  margin-top: 20px;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(26px, 2.6vw, 36px);
  line-height: 1.1;
  letter-spacing: -.014em;
  color: var(--green);
}
.reasons__lede {
  margin-top: 14px;
  font-size: 15.5px;
  line-height: 1.58;
  color: var(--ink-mid);
}
.reasons__claim .btn {
  margin-top: clamp(20px, 2.2vw, 28px);
  border-radius: 4px;
}

.reasons__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* A shade below the page ground, so the panel reads as something set down on
     the page rather than a hole in it — which is the relationship the mock
     draws. Not --cream-deep: that is the beige the client asked us out of, and
     this is mixed towards grey instead. --cream itself is exactly the body
     colour, so a panel painted with it is invisible on a white-toned section. */
  background: #F0EFEA;
  border-radius: var(--r-panel);
  /* No padding, so the hairlines run to the panel's edge as they do in the
     mock; `overflow` is what stops a cell's border cutting across the corner
     radius on the way. */
  overflow: hidden;
}
.reasons__grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.reasons__grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.reason {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 12px;
  padding: clamp(16px, 1.7vw, 22px);
  /* Hairlines between the cells, never around the panel — the rounded corner
     is the panel's edge and a border would cut across it. Reset per row and
     per column below. */
  border-left: 1px solid var(--rule);
  border-top: 1px solid var(--rule);
}
.reasons__grid--2 .reason:nth-child(2n + 1),
.reasons__grid--4 .reason:nth-child(4n + 1),
.reasons__grid .reason:nth-child(3n + 1) { border-left: 0; }
.reasons__grid--2 .reason:nth-child(-n + 2),
.reasons__grid--4 .reason:nth-child(-n + 4),
.reasons__grid .reason:nth-child(-n + 3) { border-top: 0; }

.reason__icon {
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--green);
  flex: none;
}
.reason__icon svg { width: 24px; height: 24px; }
.reason__title {
  font-family: var(--body);
  font-weight: 600;
  font-size: 15.5px;
  line-height: 1.3;
  color: var(--green);
  /* The glyph is 34px tall and the title one line — without this the title
     sits at the top of the cell and the icon floats below it. */
  padding-top: 6px;
}
.reason__words p {
  margin-top: 7px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-mid);
}

@media (max-width: 1000px) {
  /* The claim stops being a column and becomes a heading over the panel. */
  .reasons { grid-template-columns: 1fr; gap: clamp(22px, 3vw, 32px); }
  .reasons__grid,
  .reasons__grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .reasons__grid .reason:nth-child(3n + 1),
  .reasons__grid--4 .reason:nth-child(4n + 1) { border-left: 1px solid var(--rule); }
  .reasons__grid .reason:nth-child(odd) { border-left: 0; }
  .reasons__grid .reason:nth-child(-n + 3),
  .reasons__grid--4 .reason:nth-child(-n + 4) { border-top: 1px solid var(--rule); }
  .reasons__grid .reason:nth-child(-n + 2) { border-top: 0; }
}
@media (max-width: 620px) {
  .reasons__grid,
  .reasons__grid--2,
  .reasons__grid--4 { grid-template-columns: minmax(0, 1fr); }
  .reasons__grid .reason { border-left: 0; border-top: 1px solid var(--rule); }
  .reasons__grid .reason:first-child { border-top: 0; }
}

/* --- card grid: the optional glyph ---------------------------------------- */

/* `cardGrid` gained an optional icon so the four routes on /get-involved/ and
   the card blocks on its three form pages can be picked out at a glance. Every
   card the mockup seeded leaves it empty and is unchanged. */

.card__icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: rgba(20, 69, 47, .07);
  color: var(--green);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.card__icon svg { width: 24px; height: 24px; }

/* Reversed out of a dark ground the tint has to come from the light side, and
   the glyph with it — see the note on Icon's strokeWidth. */
.card--ondark .card__icon {
  background: rgba(242, 236, 221, .10);
  color: var(--on-dark);
}

/* A flat card is a green rule with words under it. A filled tile directly
   beneath that rule reads as two headers, so here the glyph stands on its own. */
.card--flat .card__icon {
  width: auto;
  height: auto;
  border-radius: 0;
  background: none;
  justify-content: flex-start;
}

/* --- event rows ----------------------------------------------------------- */

/* Date, what happened, and whether it is coming or gone.
   Three columns on a desk, stacked on a phone. This was written as an inline
   grid on the element, which meant no breakpoint could reach it: the 150px date
   column and the timing chip together overflowed a 360px screen by 24px and
   took the whole page sideways with them. A class can be told to stop. */
.eventrow {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 24px;
  align-items: baseline;
  padding-block: 22px;
  border-bottom: 1px solid var(--rule);
}
.eventrow__when { min-width: 150px; }

@media (max-width: 620px) {
  /* One column, and the timing chip moves up beside the date rather than
     sitting under the text where it reads as a caption for it. */
  .eventrow {
    grid-template-columns: auto 1fr;
    gap: 6px 14px;
    align-items: start;
  }
  .eventrow__when { min-width: 0; }
  .eventrow > div { grid-column: 1 / -1; }
  .eventrow__timing { grid-row: 1; grid-column: 2; justify-self: end; }
}

/* --- shelf dots: a target a thumb can actually hit ------------------------- */

/* The dot stays 7px because that is the design; the target does not.
   WCAG 2.5.8 asks for 24px, and the usual escape — "another control does the
   same job" — does not apply here: the arrows are deliberately hidden at 640px
   and under, so on a phone these dots are the only control on the shelf.
   A pseudo-element carries the hit area so the visual rhythm is untouched. */
.shelf__dot { position: relative; }
.shelf__dot::before {
  content: '';
  position: absolute;
  /* 7px dot + 8.5px each side = 24px. */
  inset: -8.5px;
}
/* Room for those targets to sit side by side without overlapping, which is the
   other half of what 2.5.8 asks. 7px dot + 17px gap = 24px centre to centre. */
.shelf__dots { gap: 17px; }

/* --- the pair of figures on a stat card ----------------------------------- */

/* Two side by side, which is the point — the figures are read against each
   other. But two columns inside a card inside a page gutter leaves about 110px
   each on a small phone, and a 38px numeral above its caption does not fit in
   110px; it wraps mid-label and stops reading as a pair at all. Below 560 they
   stack, still adjacent, just vertically. Was an inline grid, so no breakpoint
   could say any of this. */
.statpair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
  margin-top: 8px;
}
@media (max-width: 560px) {
  .statpair { grid-template-columns: 1fr; gap: 18px; }
}

/* --- the gold rule under an eyebrow --------------------------------------- */

/* One bar, two placements. It was written twice — `.shelftop__rule` and
   `.midhead__rule` — differing only in whether the left margin was 0 or auto,
   which is not a reason for two rules. The bottom margin differed by 2px
   between them, which was drift rather than intent. */
.eyerule {
  width: 44px;
  height: 3px;
  margin: 12px 0 14px;
  background: var(--gold);
}
.eyerule--centred { margin-inline: auto; margin-bottom: 16px; }

/* --- the mobile menu, where you can actually see it ----------------------- */

/* The panel now lives inside the sticky masthead rather than beside it.
   Before, it was a sibling in normal flow: tapping the burger halfway down a
   page did open it — correctly, with data-open set — but it opened at its
   place in the document, which by then was well above the top of the screen.
   The menu appeared to do nothing at all unless you were already at the top.

   Inside the header it travels with the bar, so it opens under the burger
   wherever you happen to be reading. */
.masthead .mobile-nav {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  /* Above the page, below nothing. The masthead itself is z-index 50. */
  z-index: 49;
  box-shadow: 0 18px 36px rgba(20, 69, 47, .13);
  /* A long menu on a short phone must not run off the bottom with no way back;
     it scrolls inside itself instead. 100dvh accounts for the address bar. */
  max-height: calc(100dvh - 100%);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* --- the very small phone -------------------------------------------------- */

/* 320px is still a real screen — the first iPhone SE and a good deal of the
   budget Android the trust's own volunteers carry. Two things did not fit
   there, and both pushed the whole page sideways.

   The masthead: brand, burger and the gold Donate button need more than the
   280px that is left of 320 once the gutters are taken. The line button is
   already dropped at 1080; below 400 the gold one goes too. Nothing is lost —
   Donate, Partner with us and Sign in are all in the menu behind the burger,
   which is exactly what the burger is for. */
@media (max-width: 400px) {
  .masthead__cta { display: none; }
}

/* The hero's page dots: ten of them at 26px with 8px between is 332px, which
   overhangs a 320px screen on its own. They scale down rather than wrap, since
   a second row of dots would sit on top of the headline. */
@media (max-width: 460px) {
  .hero__dots { gap: 5px; }
  .hero__dot { width: 16px; }
}

/* The four figures in the impact band drop to two columns at 860. On a 320px
   screen two columns leave about 96px beside a 28px icon, and "Communities
   Impacted" does not fit in 96px — it pushed the band, and the page, sideways.
   One column below 460, and the text block is allowed to shrink: a flex item
   defaults to min-width auto, which is what stops a long caption wrapping and
   makes it overhang instead. */
@media (max-width: 460px) {
  .impactband__figures { grid-template-columns: 1fr; row-gap: 16px; }
}
.impactband__figure > div { min-width: 0; }
.impactband__cap { overflow-wrap: anywhere; }

/* --- legibility and reach -------------------------------------------------- */

/* These sizes came from the mockup, where they were judged on a desk. This site
   is read on a cheap Android in daylight by a volunteer, and on a compliance
   page by somebody checking a registration number. 8.5px mono at .2em tracking
   is decorative at that point rather than readable.
   
   Raised to a floor, not redesigned: the type keeps its weight, tracking, case
   and colour, so the mockup's character is unchanged. Only the floor moves. */
.brand__sub { font-size: 10.5px; }
.hero__credit { font-size: 11px; }
.impact__cap { font-size: 11.5px; }
.doc__meta { font-size: 11.5px; }

/* The utility bar's links — the phone number, WhatsApp, Sign in — were 12 to
   13px tall as targets, which is half what a thumb needs. The bar has room:
   padding gives the height without moving the text or changing the bar. */
.utility a {
  padding-block: 6px;
  min-height: 24px;
}

/* The hero's page indicators are 3px-tall bars by design, and they stay that
   way. The target does not: a transparent box takes the tap, the same approach
   as the shelf dots. Without it they are the least hittable control on the
   site — and on the home page, the first one anybody meets. */
.hero__dot { position: relative; }
.hero__dot::before {
  content: '';
  position: absolute;
  inset: -11px -3px;
}

/* =============================================================================
   ROUND · Blog (September 2026)

   The index at /blog/ and the article at /blog/<slug>/. No client mock: built
   from the site's own parts — the crumbs, the stamp, the media card, the
   display face — so an article reads as a page of this site rather than a
   template dropped into it.

   The article column is 760px: about seventy characters of body text a line,
   which is where reading speed and comprehension both hold up.
   ========================================================================== */

.blogindex__head { padding-bottom: 0; }
.blogindex__head h1 { margin: clamp(18px, 2.4vw, 30px) 0 12px; color: var(--green); }
.blogindex__head .lede { max-width: 62ch; margin: 0; }
.blogindex__list { padding-top: clamp(30px, 3.6vw, 52px); }

.blogcard .media-card__title { margin: 0; }
.blogcard__stamp { border-top: 0; padding-top: 0; margin-top: 0; }
.blogcard .body-s {
  margin: -4px 0 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin-top: clamp(36px, 4vw, 56px);
  padding-top: 22px;
  border-top: 1px solid var(--rule);
}

/* --- the article ---------------------------------------------------------- */

.article { background: var(--white); padding-bottom: clamp(48px, 6vw, 88px); }
.article__column { max-width: 760px; margin-inline: auto; }
.article__head { padding-bottom: clamp(26px, 3vw, 40px); }
.article__stamp { border-top: 0; padding-top: 0; margin: clamp(24px, 3vw, 40px) 0 16px; }
.article__title { margin: 0 0 18px; color: var(--green); text-wrap: balance; }
.article__lede { margin: 0 0 24px; }

.article__byline {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  font: 400 14.5px/1.4 var(--body);
  color: var(--ink-mid);
}
.article__byline img { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; }
.article__byline strong { color: var(--ink); font-weight: 600; }
.article__byline small { display: block; font-size: 13px; color: var(--ink-soft); }

.article__cover { max-width: 1160px; margin: 0 auto clamp(32px, 4vw, 56px); }
.article__cover img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 640px;
  object-fit: cover;
  background: var(--cream-deep);
}
.article__cover figcaption { margin-top: 10px; font: 400 13px/1.5 var(--body); color: var(--ink-soft); }

/* Three columns so the body sits centred with the contents list in the left
   gutter beside it — out of the way, and still in view while reading. */
.article__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 760px) minmax(0, 1fr);
  column-gap: clamp(24px, 4vw, 56px);
  align-items: start;
}
.article__main { grid-column: 2; min-width: 0; }

.article__toc {
  grid-column: 1;
  grid-row: 1;
  justify-self: end;
  width: 100%;
  max-width: 230px;
  position: sticky;
  top: 110px;
  font: 400 14px/1.45 var(--body);
}
.article__toc ol { list-style: none; margin: 12px 0 0; padding: 0; border-left: 1px solid var(--rule-strong); }
.article__toc a {
  display: block;
  margin-left: -1px;
  padding: 5px 0 5px 14px;
  border-left: 2px solid transparent;
  color: var(--ink-mid);
  text-decoration: none;
}
.article__toc a:hover { color: var(--green); border-left-color: var(--gold); }
.article__toc .article__toc-sub a { padding-left: 26px; font-size: 13.5px; }

@media (max-width: 1180px) {
  .article__layout { grid-template-columns: minmax(0, 760px); justify-content: center; }
  .article__main, .article__toc { grid-column: 1; grid-row: auto; }
  .article__toc {
    position: static;
    max-width: none;
    justify-self: stretch;
    margin-bottom: 32px;
    padding: 18px 20px;
    background: var(--cream-soft);
  }
}

.prose { font: 400 clamp(17px, 1.25vw, 18.5px)/1.72 var(--body); color: var(--ink); }
.prose p, .prose ul, .prose ol { margin: 0 0 1.15em; }
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }
.prose h2, .prose h3 { font-family: var(--display); font-weight: 500; color: var(--green); scroll-margin-top: 110px; }
.prose h2 { margin: 1.9em 0 0.6em; font-size: clamp(25px, 2.2vw, 31px); line-height: 1.2; letter-spacing: -0.01em; }
.prose h3 { margin: 1.6em 0 0.5em; font-size: clamp(20px, 1.6vw, 23px); line-height: 1.3; }
/* The mockup resets lists to bare for its navigation and grids; an article's
   lists are lists, and get their markers back. */
.prose ul, .prose ol { padding-left: 1.3em; }
.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
.prose li { padding-left: 0.2em; }
.prose li + li { margin-top: 0.4em; }
.prose li::marker { color: var(--gold); }
.prose strong { font-weight: 600; }
.prose a {
  color: var(--green);
  text-decoration: underline;
  text-decoration-color: var(--gold);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}
.prose a:hover { color: var(--gold); }
.prose blockquote {
  margin: 1.6em 0;
  padding: 4px 0 4px 24px;
  border-left: 3px solid var(--gold);
  font-family: var(--display);
  font-size: 1.18em;
  font-style: italic;
  line-height: 1.5;
  color: var(--green);
}
.prose blockquote p { margin: 0 0 0.6em; }
.prose blockquote p:last-child { margin-bottom: 0; }

.article__updated {
  margin: 32px 0 0;
  font: 500 11px/1.4 var(--mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.article__project {
  margin: 28px 0 0;
  padding: 18px 20px;
  background: var(--cream-soft);
  border-left: 3px solid var(--green);
  font-size: 15.5px;
}

.article__share {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  margin-top: 36px;
  padding-top: 22px;
  border-top: 1px solid var(--rule);
}
.article__share a {
  font: 600 14px/1 var(--body);
  color: var(--green);
  text-decoration: none;
  border-bottom: 1.5px solid var(--gold);
  padding-bottom: 3px;
}
.article__share a:hover { color: var(--gold); }

/* The staff preview's reminder that this is not the live site. */
.previewbar {
  margin: 0;
  padding: 9px 16px;
  background: var(--gold-bright);
  color: var(--ink);
  font: 600 13px/1.4 var(--body);
  text-align: center;
}
