/* GGF site stylesheet. Extracted verbatim from the approved v7 homepage on 10 August 2026 so
   every page carries the identical Plan International header, giving widget and footer.
   v7 remains the reference for this file: change it here, not in a page. */



/* THE GIVING SECTION. Reuses .themes, .sec-eyebrow, h2, .sec-intro, .btn-yellow, .figtag and
   .note from brand.css. Colour logic follows the strongest Plan offices: selection is Plan
   Blue, yellow belongs to the one CTA. Each new rule is annotated with its reason. */
/* Designations: the .themes strip IS the radio group. The blue fill follows the choice, so on
   load it reads exactly like the mission strip with Annual giving (the default) filled. */
/* Above 860px the two money questions sit side by side across the full measure, so both are
   answered at a glance (Plan Germany's layout) and the band keeps v1's deceleration. */
/* Money options: square blocks, grey keyline at rest (the hairline measured 1.1:1 on the tint
   band, under the 3:1 non-text guideline, so it did not read as a control), Plan Blue when
   chosen. Focus ring: yellow, not the "blue focus ring" this comment originally said (Matthew,
   6 September 2026: "one can't be blue and one can't be yellow... use all yellow" — every other
   control in the panel, .gp-opt/.gp-select/.tlink, already was; this was the one leftover). */
/* The custom amount, revealed when Other is chosen. 16px input so phones never zoom. */
#gv-go:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}
/* One sentence of impact tied to the live selection, on the page's existing 3px yellow
   "a claim you can check" device. */
.gv-note{font-size:13px;max-width:30em;margin-top:12px}
/* The dark closer: measure cap, and a quiet text link instead of a fourth donate button. */
#close p{max-width:34em;font-size:18px}
.tlink{color:#fff;font-weight:bold;text-decoration:underline;text-decoration-color:var(--yellow);text-decoration-thickness:2px;text-underline-offset:5px}
.tlink:hover{text-decoration-thickness:3px}
.tlink:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}
.close-links{margin-top:28px}
/* Phones: the amount blocks form a tidy two-by-two, never a ragged wrap, and every button is
   full-width (the standing rule: buttons the same size on every screen; scratch-v1-language
   §6.12 ordered this for the system, so it belongs in brand.css once the module moves there). */

/* Matthew, 3 Aug: rounded edges across the page, stop the sharp corners. Plan's own strongest
   fundraising sites already do this (Plan Canada: 28px pill buttons and rounded cards; Sweden's
   header giving widget is a rounded pill), so it follows their live practice rather than the
   manual's letter. Scoped here: brand.css is shared with v1, which stays as Maureen saw it. */
.btn,.gv-cta{border-radius:999px}
.themes .cell{border-radius:var(--r)}
img.bg{border-radius:0}

/* The Other row: full row, label above, input sized to the tier blocks, currency tag attached. */

/* ============================================================================
   Matthew, 3 Aug: header, hero and footer rebuilt on the Sweden reference
   (plansverige.org, studied live in Chrome; see scratch-sweden-reference.md).
   Header and footer now bookend the page in the SAME Plan Blue object language,
   the hero goes full-bleed with the words at the bottom, and the footer becomes
   a real foundation footer: nav restate, contact, newsletter, giving rails.
   ============================================================================ */

/* The header is now fixed (it floats over the hero), so in-page anchors need an offset. */
html{scrollbar-gutter:stable}  /* scroll-padding-top is set once, in the craft pass */

/* THE HEADER: Sweden's considered object. A floating rounded Plan Blue bar, always on,
   no box-shadow (colour does the work against the page), carrying the official lockup,
   the nav, and ONE ghost donate pill (2px white keyline, transparent fill). */
header.plan{position:fixed;top:12px;left:0;right:0;background:transparent;box-shadow:none;padding:0 12px}
header.plan .wrap{background:var(--plan-blue);border-radius:999px;height:68px;padding:0 16px 0 28px}
header.plan .plan-logo{height:46px}
nav.main a{font-size:15px}
.donate-pill{font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:14.5px;color:#fff;text-decoration:none;
  border:2px solid #fff;border-radius:999px;padding:10px 22px;white-space:nowrap;transition:background .18s,transform .16s var(--ease)}
.donate-pill:hover{background:rgba(255,255,255,.14);transform:translateY(-1px)}
.donate-pill:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}
@media(max-width:860px){
  header.plan .wrap{height:58px;padding:0 8px 0 16px;gap:10px}
  /* the lockup compresses but the Foundation's name STAYS legible: smaller official
     logo, and the name wraps to two 13px lines instead of shrinking to nothing */
  header.plan .plan-logo{height:30px}
  .brandlock{gap:9px}
  .brandlock .klh{height:26px}
  .brandlock .ggf-name{font-size:13px;line-height:1.12;white-space:normal;max-width:6.6em}
  .donate-pill{margin-left:auto;font-size:13.5px;padding:8px 14px}
  .nav-toggle{margin-left:0}
  /* the dropdown hangs from the floating pill: same blue, rounded to the page's card radius */
  nav.main{left:12px;right:12px;top:calc(100% + 8px);border-radius:var(--r);overflow:hidden}
}

/* THE HERO: Sweden's geometry. The photograph fills the viewport edge to edge, the words
   sit at the BOTTOM LEFT, two pill buttons under the lead. Face safety is COMPOSITION,
   not luck, and each width band gets the bake whose geometry can prove it.
   Above 860px: v7/img/hero-wide.jpg (the vetted girls-blue photograph refetched at its
   5184px original size, Pexels id 19986547, then cropped) places the girl RIGHT of
   centre, and every text measure below stops LEFT of her face (her head spans 43
   percent of that frame, which is why phones cannot use it).
   Portrait tablets, 561 to 860px: v7/img/hero-tablet.jpg, a 3:4 crop of the whole
   vetted girls-two scene. BOTH girls are deliberately in frame (girls only, neither
   sliced), and because the bake's aspect ratio is at least every portrait viewport's,
   the full image height always shows, which PINS both faces between 12 and 35 percent
   of the viewport, far above the words at ~65 percent.
   Phones, up to 560px portrait: v7/img/hero-tall.jpg, the vetted girls-two frame from
   x620 rightward. The second girl is out of frame except a fingernail-width sliver of
   her dress at the far bottom-left (source x620-650, y1200-1410), which sits under the
   .8+ scrim and the words block at every phone width; cropping past her dress (x660)
   would put the seated girl's own head at the frame edge, the worse trade. */
.hero-editorial{min-height:100vh;min-height:100svh;padding:0} /* the generic section padding must not inflate the full-bleed hero */
.hero-editorial .bg{object-position:100% 30%}
/* Sweden's own inset: the hero words leave the 1180 grid and sit near the left edge
   (plansverige.org insets them 13 to 100px). That buys the face-clearance margin AND the
   words-at-the-bottom presence. Everything else on the page stays on the grid. */
.hero-editorial .wrap{max-width:none;padding-left:clamp(24px,4vw,64px);padding-right:clamp(24px,4vw,64px);padding-top:calc(var(--hdr) + 28px);padding-bottom:clamp(40px,6vh,72px);width:100%}
/* 4.5vw (not v1's 6.2vw): the longest line ("the smartest thing") then holds under half the
   viewport, always clear of the girl's face at 56 percent of the frame. Still capped at the
   full 78px display tier on wide screens. The lead is capped the same way: its em-measure
   is fixed while the face position scales with the viewport, so 27em is the widest that
   stays clear at 1280. The hero kicker moved into the impact stats band for the same
   reason: it grew the hero past the viewport, which re-cropped the photograph and slid
   the face left under the text at laptop heights (and it fell below the fold anyway). */
.hero h1{font-size:clamp(38px,4.5vw,78px);max-width:10.6em}
.hero .lead{max-width:27em}
@media(min-width:861px) and (max-width:1200px){ .hero .lead{max-width:24em} }
/* The scrim: v1's engineered horizontal gradient (alpha .78+ across the whole text column,
   worst-case white behind still passes AA) plus Sweden's bottom lift under the buttons. */
.hero-editorial .scrim{background:
  linear-gradient(0deg,rgba(6,26,42,.5) 0%,rgba(6,26,42,0) 42%),
  linear-gradient(90deg,rgba(6,26,42,.92) 0%,rgba(6,26,42,.78) 45%,rgba(6,26,42,.5) 100%)}
/* Between 861 and 1200px a full-height hero would narrow the crop window and slide the
   girl's face left into the text zone; capping the hero at the crop's own aspect keeps
   the full width of the picture (and the face clear) at every window in the range. */
@media(min-width:861px) and (max-width:1200px){
  .hero-editorial{min-height:calc(100vw/1.6)}
}
/* The kicker figure now lives in the stats band: four evidence figures, one pattern.
   Wide screens only: an unscoped override here beats brand.css's OWN media queries (same
   specificity, later sheet), which re-imposed four columns on phones and pushed the page
   134px past a 390 viewport. Below 861px brand.css stacks the stats 2x2 then single file. */
@media(min-width:861px){ .stats{grid-template-columns:repeat(4,1fr)} }
/* Portrait tablet, 561 to 860px: the two-girl 3:4 bake. No vertical overflow at any
   portrait aspect, so the faces cannot slide under the words: geometry first, then
   verified by eye. object-position vertical is a no-op here on purpose. */
@media(max-width:860px) and (orientation:portrait){
  .hero-editorial .bg{object-position:50% 50%}
  /* the words start at 46 percent on the smallest portrait tablets (561x748, measured
     live) and ~61 to 66 percent on iPads, so the ramp reaches .78 by 46 percent; both
     faces bottom out at 34.7 percent, just above the ramp's start */
  .hero-editorial .scrim{background:linear-gradient(180deg,rgba(6,26,42,.22) 0%,rgba(6,26,42,.3) 38%,rgba(6,26,42,.78) 46%,rgba(6,26,42,.94) 100%)}
  .hero-editorial .wrap{padding-bottom:34px}
  .hero .lead{margin:20px 0 26px}
}
/* Phone portrait, up to 560px: the tall crop, face top, words bottom. The girl's face
   spans 21.4 to 37.6 percent of the tall bake's height; cover leaves vertical overflow,
   and object-position 50% 60% lifts her face fully above the worst-case text start.
   The type steps down here so the words block stays under ~470px tall: that is what
   buys the face its clearance on 640px-tall Androids. Checked BY EYE at 360x640,
   375x667, 390x844 and 430x932 (3 Aug). */
@media(max-width:560px) and (orientation:portrait){
  .hero-editorial .bg{object-position:50% 60%}
  /* The scrim is built from the BOTTOM in px because the words are bottom-anchored:
     the measured worst-case first text line is 441px from the bottom (360 wide, with
     the 374px tier below) and 436px at 375 to 430 wide, so alpha holds .8 through
     444px, then falls fast so the ramp never climbs into her chin (the chin sits
     473px from the bottom on a 360x640 viewport, the tightest case). */
  .hero-editorial .scrim{background:linear-gradient(0deg,rgba(6,26,42,.94) 0,rgba(6,26,42,.86) 340px,rgba(6,26,42,.8) 444px,rgba(6,26,42,.3) 462px,rgba(6,26,42,.21) 100%)}
  .hero-editorial .wrap{padding-bottom:26px}
  .hero h1{font-size:33px;line-height:1.18}
  .hero .lead{font-size:15.5px;margin:14px 0 20px}
  /* the eyebrow holds ONE quiet line at 11px from 375px up (verified live) and wraps
     to two lines on the 360-class tier below; the scrim and focal maths assume the
     two-line worst case, so the code and the rendered truth match */
  .hero .eyebrow{font-size:11px;letter-spacing:.09em;margin-bottom:14px}
  .hero .eyebrow::before{display:none}
}
/* The 360-class tier. Measured live: at 360 wide the words block runs 493px tall and
   the first line lands INSIDE the face band on a 640px viewport (the small-Android +
   iPhone SE class the panel flagged). The compression is WIDTH-scoped because the
   block's height is set by wrap count, not viewport height: a 360x700 screen needs it
   as much as 360x640. Every .btn on the page compresses together, so buttons stay
   identical to each other at any given width. Below ~340px the geometry cannot hold
   (the face band alone is 24 percent of a 568px viewport); 320x568-class devices are
   a documented limitation, not a silent one. */
@media(max-width:374px) and (orientation:portrait){
  .hero h1{font-size:30px}
  .hero .eyebrow{margin-bottom:10px}
  .hero .lead{margin:10px 0 16px}
  .hero-editorial .wrap{padding-bottom:20px}
  .btn{padding:12px 22px;font-size:15.5px}
  .cta-row{gap:10px}
}

/* THE FOOTER: the Sweden architecture in our tokens, six layers top to bottom: identity
   row, hairline, nav restate (one BIG column + underlined columns), hairline, contact +
   newsletter, then a full-width darker giving-rails strip. Same Plan Blue as the header:
   the bookend. Every unknown value is a LABELLED placeholder in Georgia italic (the
   page's caveat voice); never an invented number that could be mistaken for a real
   bank detail, phone number or registration. */
footer.plan{padding:0;font-size:15px}
footer.plan .ft-main{padding:clamp(44px,6vw,72px) 0 clamp(32px,4vw,48px)}
footer.plan p{color:#fff} /* .9 white on Plan Blue measures 4.26:1, under AA; solid white passes */
/* flex-start, not space-between: on a wide screen space-between threw the strapline a thousand
   pixels from the lockup, so the two halves of one identity read as unrelated. */
.ft-top{display:flex;align-items:flex-end;justify-content:flex-start;gap:clamp(28px,4vw,72px);flex-wrap:wrap;margin-bottom:38px}
.ft-lockup img{height:clamp(56px,6vw,76px);width:auto;display:block}
.ft-strap .strapline{margin-bottom:6px}
.ft-arm{font-size:14px}
.ft-rule{border:0;border-top:1px solid rgba(255,255,255,.3);margin:0}
/* FIVE PEER COLUMNS, one row. This was a two-column grid holding a three-column grid in one
   cell and a two-column grid in the other, which squeezed the newsletter input to 107px so it
   could not show its own placeholder, left 98px of empty blue under it, and gave five columns
   of equal standing five different widths. The newsletter column keeps a wider minimum,
   because it holds a form and the others hold lists. */
.ft-grid{display:grid;grid-template-columns:repeat(4,minmax(140px,1fr)) minmax(300px,1.5fr);
  gap:clamp(22px,2.2vw,48px);padding:30px 0}
/* A column stuck at its content width pushed the document 44px sideways below about 366px,
   which is an iPhone SE and any phone with Display Zoom on. */
.ft-col{min-width:0}
.ft-col h3{font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:17px;color:#fff;margin:0 0 12px}
.ft-col a{display:block;color:#fff}
/* Emphasis, but not so much that a five-word label wraps inside its own column, and underlined:
   the four largest items in the footer used to be the four that did not look clickable, while
   every 15px item was underlined. That is the hierarchy upside down. */
.ft-col a.big{font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:clamp(17px,1.15vw,20px);
  line-height:1.35;padding:5px 0;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:5px}
.ft-col a.big:hover{text-decoration-thickness:2px}
.ft-col a.sm{font-size:15px;line-height:1.5;padding:5px 0;text-decoration:underline;text-underline-offset:3px}
.ft-col a.sm:hover{text-decoration-thickness:2px}
.ft-col a:focus-visible{outline:3px solid var(--yellow);outline-offset:2px}
.ft-col p{margin:0 0 8px;line-height:1.6;font-size:15px}
.ft-col p a{display:inline;text-decoration:underline;text-underline-offset:3px}
.ft-addr{font-size:14.5px}
.ft-contact p{margin:0 0 8px;line-height:1.6}
.tbc{font-family:Georgia,'Times New Roman',serif;font-style:italic}
.ft-news>p{margin:0 0 14px;max-width:34em}
/* Sweden's pill-in-pill newsletter form: a darker-blue rounded container, borderless
   input, solid white pill button with Plan Blue text. */
.nl-pill{display:flex;align-items:center;background:var(--plan-blue-dk);border-radius:999px;padding:8px 8px 8px 24px;max-width:460px}
.nl-pill input{flex:1;min-width:0;background:transparent;border:0;color:#fff;font-size:16px;font-family:inherit;padding:10px 8px 10px 0;outline:none}
.nl-pill input::placeholder{color:rgba(255,255,255,.8)}
.nl-pill:focus-within{outline:3px solid #fff;outline-offset:2px}
.nl-btn{background:#fff;color:var(--plan-blue);border:0;border-radius:999px;font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:15px;padding:12px 24px;cursor:pointer;transition:transform .16s var(--ease)}
.nl-btn:hover{transform:translateY(-1px)}
.nl-msg{margin-top:10px;font-size:14px;min-height:1.5em}
.rail{min-width:180px}
.rail-h{display:block;font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:15px;color:#fff;margin-bottom:3px}
.rail .tbc{color:#fff;font-size:14.5px}
/* The visible caveat line under the social icons and the planned-pages column: the
   Georgia voice every other unknown on the page already speaks. */
/* The closing legal microline, Sweden's org-number row equivalent. No border-top: the
   background already steps from Plan Blue to the dark, and drawing a hairline on a colour
   change is the third of the four dividing devices Matthew was looking at. */
.ft-legal{background:var(--plan-blue-dk);padding:15px 0}
.ft-legal p{margin:0;font-size:13.5px}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
@media(max-width:860px){
  .ft-grid{grid-template-columns:1fr}
  .ft-top{align-items:flex-start;flex-direction:column}
}

/* Matthew, from the screenshot: the "Your amount" label was centred over the field instead of
   left-aligned, and the designation cards touched each other and were unequal. */

/* The three designation cards: separated, and identical in width and height. Grid gives equal
   columns; stretch makes every card the height of the tallest, so no card is short. */

/* Trust marks: quiet, in a row, never competing with the button they reassure. */


/* Matthew: "we're using rounded corners, so the picture needs rounded corners also, we can't
   have square and circles." Every inline photograph and the logo lockup now match the page's
   rounded scale. The full-bleed hero stays square: a radius on an edge-to-edge image reads as a
   rendering fault, not a decision. */
/* .plan-logo itself is gone from the markup (the header it belonged to was removed), but the
   exclusion for it costs nothing to keep. :not(.lr-shot img), added earlier the same day to fix
   a specificity fight this rule was winning against .lay-round's circular-photo crop, came back
   out when .lay-round itself was removed a few hours later — see the ROUND comment near
   .lay-split above. */
#case img,section img:not(.bg):not(.plan-logo){border-radius:var(--r)}
/* 11 September 2026: a photo dropped into a Section body (WordPress's own Image block) offers
   exactly the two photo shapes already used elsewhere on the site, registered in
   assets/inline-blocks.js as this block's only two style choices: "Square" is nothing more than
   the soft corner every photo in a section already gets from the rule just above, so it needs no
   CSS of its own; "Round" matches the circular crop People already uses for a portrait
   (.is-portraits .reg-shot, a few hundred lines down). No third option, no arbitrary corner
   radius: a photo added here can only ever end up looking like it belongs to this design. */
.wp-block-image.is-style-ggf-round img{border-radius:50%;aspect-ratio:1;object-fit:cover}

/* ── THE GIVING SECTION, REWORKED ──────────────────────────────────────────────
   Matthew, from the browser: the third card looked cut off, the gaps between Currency, How
   much and Your amount were unequal, and "How often" sat orphaned in a right-hand column while
   the other questions ran full width. Measured: the four groups were 1100 / 514 / 514 / 1100 px
   wide with 206px then 109px vertical gaps. That is three different rhythms in one form.
   Now: ONE column, every question the same width, the same gap between each. A form should read
   as a single descending sequence, not a grid puzzle. */
/* This restated rule silently KILLED the phone layout. The single-column rule for the designation
   cards lives at line 291, inside @media(max-width:760px); a media query adds no specificity, so
   three cards stayed in three columns at 63px each and the third label ran 25px off the right edge
   of the page. Measured in a real 390px frame, not a headless window. Re-declare it AFTER. */

/* The sticky bar was covering the form it points at. Leave room for it, and let the page settle
   back when it is gone. */

/* ── THE DUE-DILIGENCE PANEL (replaces the trust strip) ──────────────────────────────────────
   Matthew, 3 Aug: "for the section that shows part of a plan international, the philanthropy
   council, clear governance, where your money goes, you need to think of a much nicer way to
   design that area."

   Measured in Chrome first, and the numbers say exactly why it fell flat: four items, each
   256 x 98px, transparent, identical weight. Four identical shapes cannot carry a hierarchy, so
   the donor's credibility check read as a footnote under 170px of dead space. The 14px radius was
   also landing on a 3px left RULE with nothing to round, bending it into a bracket that looked
   like a rendering fault rather than a decision.

   The redesign is not decoration. These are four different KINDS of answer and they should not
   be four identical shapes:
     Plan International  is a badge     -> show the official lockup as the evidence
     The Council         is people      -> the lead card, and a route to meet them
     Governance          is a process   -> a checked list of what is actually checked
     After you give      is a route     -> three steps, joined by the page's own yellow rule
   The section intro already promised "the questions serious donors ask first", so each card now
   states its QUESTION above its answer. That turns a list into an argument, which is the form a
   philanthropist doing due diligence actually reads, and it is Susanna's point about being a
   different proposition to a philanthropist rather than a traditional charity.

   Why the Council leads, filled and largest: Plan International already appears in the header
   lockup, the hero eyebrow and the case section. The Council appears ONLY here on the homepage,
   and Susanna has required it prominent since 14 July. The lead slot goes to the thing with
   nowhere else to be. One filled card is not Maureen's "large flat colour panel" (Plan's red
   child-marriage box) and filled Plan Blue already means "the one that leads" on this page:
   the mission flagship cell and Annual giving both use it. Same language, not a new device. */
/* THE MASTHEAD SITS ON THE SAME 12 COLUMNS AS THE CARDS. It did not, and the headline's 16em cap
   landed 38px past the lead card's right edge: a near-miss, which reads worse than either aligning
   or plainly not aligning, and it left a 430 x 170px void in the top right while the grid below
   ran the full width. Heading on 7, intro on the last 4, baselines aligned. */
.dd-head{display:grid;grid-template-columns:repeat(12,1fr);gap:18px;align-items:start;margin-bottom:var(--s4)}
.dd-head .mh-a{grid-column:span 7}
.dd-head .mh-b{grid-column:9 / span 4}
#about h2{max-width:none;margin-bottom:0}
#about .sec-intro{max-width:none;margin-bottom:4px}

.dd{display:grid;grid-template-columns:repeat(12,1fr);gap:18px}
/* 1.5px var(--grey), not var(--line). This page already had this argument once and settled it:
   the giving blocks measured a --line hairline at 1.1:1, under the 3:1 non-text guideline, and
   switched to --grey so the card would read as an object. The first pass at this panel then used
   --line anyway, which measured 1.23:1 on white, so three of the four cards were not cards at
   all, they were faint outlines around floating text. One blue rectangle and three ghosts is
   what "flat" looks like when every text contrast in the section passes.
   Radius 14, not 18: 18 existed nowhere else in the system. .themes .cell and .gv-des .cell are
   both 14, so this rejoins the page instead of inventing a token. */
.dd-card{border:1.5px solid var(--grey);border-radius:var(--r);padding:30px 32px;display:flex;
  flex-direction:column;background:#fff}
.dd-council{grid-column:span 7}
.dd-plan{grid-column:span 5}
.dd-gov{grid-column:span 7}
.dd-after{grid-column:span 5;background:var(--paper-2)}
/* No hover lift. Three of these four are not clickable, and a card that rises and glows under the
   cursor promises something it cannot do. Elevation-on-hover is also a Material habit; this page's
   hover language is a background change on regions and a lift on buttons only. */

/* The question, carrying the page's own eyebrow device: a 22 x 3 yellow rule, the same object as
   .sec-eyebrow::before. Without it these were generic small-caps captions, and yellow appeared in
   the whole 1100 x 615 panel exactly twice, at 20 x 3px each. The brand's punctuation now marks
   all four answers, which is the fastest possible read of "one family, and it is this page's".
   It lives INSIDE the h3, so a screen reader hears "Who decides where it goes? The Philanthropy
   Council" as one heading instead of four orphan questions floating before four headings. */
.dd-q{display:flex;align-items:center;gap:10px;font-family:'Poppins',Arial,sans-serif;
  font-weight:700;font-size:13px;line-height:1.25;letter-spacing:.14em;text-transform:uppercase;
  color:var(--grey);margin:0 0 12px}
.dd-q::before{content:"";width:22px;height:3px;border-radius:999px;background:var(--yellow);flex:none}
.dd-card h3{font-size:clamp(20px,1.75vw,25px);line-height:1.15;letter-spacing:-.01em;
  color:var(--plan-blue);margin:0 0 12px}
/* The 7-column card gets a bigger answer as well as more room, so the width means something.
   It also caps its measure: at 15.5px in a 7-column card the line ran to 79 characters. */
.dd-gov h3{font-size:clamp(22px,1.95vw,28px)}
.dd-card p{font-size:15.5px;line-height:1.62;color:var(--grey);margin:0;max-width:34em}

/* The lead card. Bigger type as well as a fill, because a colour change alone is emphasis by
   paint; scale is emphasis by design. */
.dd-lead{background:var(--plan-blue);border-color:var(--plan-blue)}
/* Both of these are PURE white, not tinted, and that is a contrast decision rather than a taste
   one. Measured: white at 74% over Plan Blue composites to #BDDAF2, which is 3.4:1 against the
   card and fails WCAG AA for a 12.5px label; at 93% the body copy lands on 4.54:1, passing by a
   margin too thin to defend. Pure white on Plan Blue is 4.95:1. The hierarchy is carried by size
   and weight instead, which is how the hero already does it. */
.dd-lead .dd-q{color:#fff}
.dd-lead h3{color:#fff;font-size:clamp(25px,2.3vw,33px)}
.dd-lead p{color:#fff;font-size:17px;max-width:30em}
/* The caveat voice the rest of the page already uses for anything not yet confirmed (.tbc in the
   footer, .note in brand.css): Georgia italic. The card promised "real names" and showed none,
   which a philanthropist reads as a promise of specificity delivered as an empty blue rectangle.
   Until GGF supply the Council, the page says so in its own convention rather than leaving an IOU. */
.dd-tbc{font-size:14px;margin-top:20px}
/* Pure white again, not 86%: tinted white over Plan Blue measures 4.07:1 at 14px and fails AA.
   Georgia italic is doing the "this is a caveat" work, so the colour does not have to. */
.dd-lead .dd-tbc{color:#fff}
.dd-tbc{color:var(--grey)}

/* One link per card, pinned to the bottom so the cards agree on a baseline even at unequal
   heights. The arrow is drawn, not typed: a glyph would render differently in every fallback. */
.dd-link{margin-top:auto;padding-top:14px;align-self:flex-start;display:inline-flex;align-items:center;
  gap:9px;font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:15px;
  color:var(--plan-blue);text-decoration:none}
.dd-lead .dd-link{color:#fff}
.dd-link svg{width:17px;height:17px;transition:transform .2s var(--ease)}
.dd-link:hover svg{transform:translateX(4px)}
.dd-link:hover span{text-decoration:underline;text-underline-offset:4px}
.dd-link:focus-visible{outline:3px solid var(--yellow);outline-offset:4px;border-radius:var(--r-sm)}

/* The badge: the official lockup Daniela supplied, presented as the evidence rather than described
   in a sentence. Left-aligned on the card's own text edge. The hairline that used to sit above it
   is GONE: the card's content filled its row height almost exactly, so margin-top:auto had nothing
   left to distribute and the rule landed 9px under a descender, where it read as an underline of
   the paragraph rather than as a frame for the mark. Clearance does that job instead.
   No radius: the lockup is a supplied asset and rounding its corners would be altering it. */
.dd-mark{margin-top:auto;padding-top:40px}
.dd .dd-card .dd-mark img{width:100%;max-width:214px;height:auto;display:block;border-radius:0}

/* Governance: what is checked, in the page's OWN list language (.feature-points in brand.css):
   a hairline above each row and a 14 x 3 yellow rule at the left edge. The first pass used filled
   blue discs with white check marks, which exist nowhere else on this page and made a governance
   panel look like a SaaS pricing table. This also puts yellow into the composition three more
   times. Items still to be confirmed by GGF carry the page's Georgia-italic caveat voice, so the
   card never asserts an audit the footer says is pending two screens below. */
.dd-checks{list-style:none;margin:20px 0 0;padding:0}
.dd-checks li{position:relative;padding:11px 0 11px 30px;border-top:1px solid var(--hairline);
  font-size:15.5px;line-height:1.45;color:var(--ink)}
.dd-checks li::before{content:"";position:absolute;left:0;top:19px;width:14px;height:3px;
  border-radius:999px;background:var(--yellow)}
.dd-checks .tbc{color:var(--grey)}
/* The three programme links (Girls in Leadership/Crisis/Innovation) are plain <a> tags with no
   class, the only links ever placed inside this list, so they fell straight through to the
   browser's own blue-and-underline default instead of the site's own link styling, found live
   7 Sep 2026. */
.dd-checks a{color:var(--plan-blue);font-weight:700;text-decoration:underline;text-underline-offset:3px}
.dd-checks a:hover{color:var(--ink)}
.dd-checks a:focus-visible{outline:3px solid var(--yellow);outline-offset:3px;border-radius:2px}

/* The route a gift takes, rebuilt. The first pass set three pill-shaped Poppins-bold Plan Blue
   labels joined by short yellow bars: character for character the page's own button shape, so it
   read as three dead buttons 200px above a real donate call to action, and the bars read as em
   dashes rather than as a route. Now it is a numbered editorial sequence on hairlines, which is
   unmistakably not a control. */
.dd-route{list-style:none;margin:20px 0 0;padding:0;counter-reset:step}
.dd-route li{counter-increment:step;display:flex;gap:14px;align-items:baseline;
  padding:11px 0;border-top:1px solid var(--line);font-size:15.5px;line-height:1.45;color:var(--ink)}
.dd-route li::before{content:"0" counter(step);font-family:'Poppins',Arial,sans-serif;
  font-weight:700;font-size:13px;color:var(--plan-blue);letter-spacing:.06em;flex:none}

/* Tablet: the two 7-column cards go full width, the two 5-column ones pair. Phone: one column.
   Verified at real widths in Chrome, not in a headless window that clamps at 500px. */
/* Tablet pairing, corrected. The first attempt kept the two 7-column cards full width and the two
   5-column ones at half, but grid fills in source order, so each half-width card landed alone on
   its own row with 344px of dead space beside it. Measured at a real 768px frame. The lead keeps
   the full width it earns; the two middle cards pair; the closing card runs full width. */
@media(max-width:1000px){ .dd-head .mh-a,.dd-head .mh-b{grid-column:span 12} .dd-head{gap:14px;margin-bottom:40px}
  .dd-council,.dd-after{grid-column:span 12} .dd-plan,.dd-gov{grid-column:span 6}
  .dd-gov h3{font-size:clamp(20px,1.75vw,25px)} }
@media(max-width:700px){
  .dd{gap:14px}
  .dd-card{grid-column:span 12;padding:24px 22px}
}
@media(prefers-reduced-motion:reduce){ .dd-link svg{transition:none} }

/* ════════════════════════════════════════════════════════════════════════════════════════════
   10 AUGUST. Matthew, from the browser, three faults and the Sweden menu pattern.
   ════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── FAULT 1. "That image has two elements behind it. They're both very square instead of
   rolling like the rest of the site, so it looks kind of funny."
   Measured: .feature-media::before is a 92px yellow square at radius 0, ::after is a 64px square
   with a 4px Plan Blue border at radius 0, and both sit behind a photograph rounded to 16px.
   A hard corner poking out from behind a soft one reads as a rendering fault. They keep their
   offsets and their job, they just stop being squares. */
.feature-media::before{border-radius:var(--r)}
.feature-media::after{border-radius:var(--r)}

/* ── FAULTS 2 AND 3. "The next section below it seems to be an overlap" and "the cards aren't
   really very separate, they seem almost connected."
   Measured: the mission strip is ONE grid with no gap (gap computed as "normal"), a square 1px
   outer frame, 1px dividers between cells, and each cell carrying a 14px radius. So three cards
   with rounded corners were butted edge to edge inside a square box. At every join a rounded
   corner pulls away from the square frame and leaves a wedge, which is exactly what reads as two
   boxes sitting on top of each other. Nothing actually overlaps: every section on this page butts
   its neighbour at 0px, verified. The overlap is the corner geometry, not the layout.
   Fix: make them what they already pretend to be. Real cards, real gaps, no frame, no dividers,
   and the same 1.5px grey keyline the trust panel and the giving cards use. Scoped to #mission
   so nothing else that borrows .themes is disturbed. */
#mission .themes{border:0;gap:18px;align-items:stretch}
#mission .themes .cell{border:1.5px solid var(--grey);border-radius:var(--r);border-right:1.5px solid var(--grey);
  height:100%;transition:border-color .2s var(--ease)}
#mission .themes .cell:hover{background:transparent;border-color:var(--plan-blue)}
#mission .themes .flag{border-color:var(--plan-blue)}
#mission .themes .flag:hover{background:var(--plan-blue)}
@media(max-width:820px){ #mission .themes{grid-template-columns:1fr} }

/* ── THE HEADER IS PLAN INTERNATIONAL'S, NOT OURS ────────────────────────────────────────────
   Matthew, 10 August: "I don't think you have got the top menu right... We need to use the
   correct menu, but I want to keep the donate widget type of thing, so you need to integrate it
   into it. Use the menu that thing there that Plan International wants us to use."

   He is right, and the previous pass was a straight mistake: it replaced Plan's mandated header
   with a floating three-pill cluster borrowed from plansverige.org. Sweden is a National
   Organisation on its own platform. GGF is a site inside Plan's shared estate and inherits the
   estate's header, which is not ours to redesign.

   So this is measured off the LIVE GGF site (globalgirlsfoundation.org, Altis/WordPress, read
   only), not invented:
     header.site-header   background #0072CE, position sticky, z-index 3, HEIGHT 100px, Arial
     .menu-toggle         112 x 100 at the far left, a hamburger with the word "Menu" under it
     nav links            16px / 700 / white, starting at x=127
     a.top-logo           137 x 81, CENTRED (x=531 in a 1200 container)
     .search-block        229 wide on the right, search plus "Plan's global sites"
     a.btn.btn-type-3.btn-donate   112 x 40, radius 44px, background #FFD500, at x=1070

   THE FINDING THAT MAKES THIS EASY: that last one is the yellow pill currently labelled
   "Contact" on the live GGF site, and its classes are btn btn-type-3 btn-donate. It is the SAME
   component the Dominican Republic site uses for its "Donar" button, which is the example Laura
   sent to confirm a top-right donate button is possible. The component is already on the page.
   We are relabelling it and hanging the giving widget off it, not asking for anything new. */
/* These three tokens were defined inside the header block that this pass replaced, and deleting
   them silently broke the giving widget: every UNSELECTED chip fell back to transparent on white
   with white text, so only the chosen option in each row was visible. Restored here, where they
   belong, because they are used across the panel and not just by the header. */
:root{ --sw:cubic-bezier(.34,.34,.02,.97); --tint:#E0EEF9; --tint-ink:#005AA6; }

header.plan{position:sticky;top:0;left:auto;right:auto;background:var(--plan-blue);
  box-shadow:none;padding:0;z-index:80}
header.plan .wrap{max-width:none;padding:0;background:transparent;border-radius:0;height:auto;display:block}

.ph-bar{position:relative;max-width:1200px;margin:0 auto;height:100px;padding:0 18px;
  display:flex;align-items:center;gap:18px}
.ph-left{display:flex;align-items:center;gap:22px;min-width:0}
.ph-right{display:flex;align-items:center;gap:18px;margin-left:auto}

/* The menu toggle: the icon with the word Menu BESIDE it, per Matthew on 11 August. It was
   stacked, icon above label, which is Plan's own arrangement, but with the three repeated nav
   links gone from the bar there is room for a row, and a row reads as one control rather than
   as two things. No fixed width any more: the button is as wide as the icon and the word. */
.ph-menu{height:100px;border:0;background:none;color:#fff;cursor:pointer;
  display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:11px;padding:0 8px 0 0}
.ph-menu .bars{position:relative;width:22px;height:12px;display:block}
.ph-menu .bars i{position:absolute;left:0;right:0;height:2px;border-radius:999px;background:#fff;
  transition:transform .3s var(--sw),opacity .2s var(--sw)}
.ph-menu .bars i:nth-child(1){top:0} .ph-menu .bars i:nth-child(2){top:5px} .ph-menu .bars i:nth-child(3){top:10px}
.ph-menu[aria-expanded="true"] .bars i:nth-child(1){transform:translateY(5px) rotate(45deg)}
.ph-menu[aria-expanded="true"] .bars i:nth-child(2){opacity:0}
.ph-menu[aria-expanded="true"] .bars i:nth-child(3){transform:translateY(-5px) rotate(-45deg)}
.ph-menu span.lbl{font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:700;line-height:1}
.ph-menu:focus-visible,.ph-sites:focus-visible,.ph-search:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}

/* .ph-nav has gone with the three links it held. They repeated menu items, and the menu now
   carries every page on the site, so the bar was showing part of the same list twice. */

/* Centred absolutely, exactly as theirs is: x=531 in a 1200 container is dead centre. */
.ph-logo{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:block;line-height:0}
/* object-fit:contain, because flex compression below 360px squeezed the parent brand mark
   25.7% horizontally instead of letting it shrink evenly */
.ph-logo img{height:74px;width:auto;display:block;object-fit:contain}
.ph-logo:focus-visible{outline:3px solid var(--yellow);outline-offset:4px}

.ph-sites{display:flex;align-items:center;gap:8px;color:#fff;text-decoration:none;
  font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:700;white-space:nowrap}
.ph-sites:hover{text-decoration:underline;text-underline-offset:4px}
.ph-sites svg,.ph-search svg{width:19px;height:19px;stroke:#fff;flex:none}
.ph-search{border:0;background:none;padding:6px;cursor:pointer;line-height:0}

/* THIRD-PARTY CSS BEGIN
   Plan International's own donate component, reproduced from their live sites rather than
   designed by us: measured identically on globalgirlsfoundation.org (labelled "Contact") and on
   plan-international.org/republica-dominicana ("Donar"), which is the example Laura Barrington
   sent on 7 August to show a top-right donate button in place. 40px tall, 44px radius, #FFD500,
   Arial 16/700. The 44px radius is outside our own shape standard, and it stays 44px because it
   is not ours to change. Fenced so the shape gate skips it and prints that it did. */
.btn-donate{display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 22px;
  border:0;border-radius:44px;background:var(--yellow);color:var(--ink);cursor:pointer;
  font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:700;white-space:nowrap;
  text-decoration:none;transition:background .2s var(--sw),transform .16s var(--sw)}
.btn-donate:hover{background:#ffdf3d;transform:translateY(-1px)}
.btn-donate:focus-visible{outline:3px solid #fff;outline-offset:3px}
/* The pill used to relabel itself to "Close" while the panel was open. Matthew, 14 August:
   it "must always say Start Giving". So it does, open or shut; the panel has its own close. */
/* THIRD-PARTY CSS END
   Everything below is ours and is checked by every guard. */

/* THE PANELS ARE DRAWERS. Matthew, 11 August: the giving dropdown floated at the right with a
   gap and stopped mid-screen, which read as misplaced, and the menu panel was a different blue
   from the header. Now: each panel is flush to its screen edge, runs from the bar to the bottom
   of the viewport, and the menu is the header's own Plan Blue. */
.panel{position:fixed;top:100px;right:0;bottom:0;width:440px;max-width:100vw;z-index:2;
  border-radius:0;padding:0 34px 34px;
  overflow-y:auto;overscroll-behavior:contain;
  visibility:hidden;opacity:0;transform:translateX(18px);transform-origin:top right;pointer-events:none;
  transition:opacity .5s var(--sw),transform .5s var(--sw),visibility 0s linear .5s}
.panel.open{visibility:visible;opacity:1;transform:none;pointer-events:auto;
  transition:opacity .5s var(--sw),transform .5s var(--sw),visibility 0s}
html.no-js .panel:target{visibility:visible;opacity:1;transform:none;pointer-events:auto;transition:none}
.panel-give{background:#fff}
/* SAME blue as the bar it hangs from, so bar and panel read as one object. It was
   --plan-blue-deep, a different navy, which is what read as "the colour is different". */
.panel-nav{background:var(--plan-blue);color:#fff;
  right:auto;left:0;transform:translateX(-18px);transform-origin:top left}
.panel-nav.open{transform:none}
.panel::before{content:"";position:sticky;top:0;z-index:1;display:block;height:26px;
  margin:0 -34px;background:inherit}

/* No backdrop-filter. A full-screen blur puts the entire page behind it on the compositor for
   every frame, and forty-one copies of this div had accumulated on the homepage, so the browser
   was compositing forty-one full-screen blurs. That is what Matthew was seeing when the page
   flickered, arrived late and went blank as he scrolled. The duplicates are fixed at the source
   and the blur has gone with them: a slightly deeper scrim reads the same and costs nothing. */
.hdr-scrim{position:fixed;inset:0;background:rgba(12,16,20,.55);
  opacity:0;pointer-events:none;z-index:75;
  transition:opacity .5s var(--sw)}
.hdr-scrim.on{opacity:1;pointer-events:auto}

/* Below the estate's own breakpoint the sites link goes into the menu, exactly as theirs does,
   and the bar keeps only: menu, centred lockup, donate. (.ph-nav no longer exists: the three
   links it held are in the menu, which is where the rest of the pages already were.) */
@media(max-width:1024px){
  .ph-sites{display:none}
  .ph-bar{height:82px;padding:0 12px}
  .ph-menu{height:82px}
  .ph-logo img{height:58px}
  .panel{top:82px}
}
@media(max-width:560px){
  .ph-bar{height:72px}
  .ph-menu{height:72px;gap:0}
  .ph-menu span.lbl{display:none}
  /* The lockup is absolutely centred on wide screens, which takes it out of the flex flow. On a
     phone that meant the giving button was painted straight over it: 24px of Plan International's
     own logo covered at 375px, which is the width the Managing Director will open this at.
     Back into the flow here, so the three items share the bar instead of stacking on each other,
     and the browser guarantees they cannot overlap rather than the arithmetic happening to work. */
  .ph-logo{position:static;transform:none;margin:0 auto;min-width:0}
  .ph-right{margin-left:0}
  .ph-logo img{height:44px;max-width:100%}
  .btn-donate{height:36px;padding:0 16px;font-size:15px}
  .panel{top:72px;width:100vw;padding:0 22px 26px}
  .panel-nav{left:0;right:auto}
  
}

/* ── PANEL A: GIVING. The Ways to Give section, compressed into 365px of usable width.
   Their order, which we adopt: how often, then what it funds, then how much. The designation is
   the control that COLLAPSES, and it earns its place: as a select it can offer the two programme
   areas by name, which the three-card version could not without a fourth and fifth card.
   Maureen's order is preserved inside it: annual giving first. */
.gp-q{font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:13px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--plan-blue);margin:0 0 6px;display:block}
/* Matthew, 6 September 2026: opening the panel meant scrolling to reach the amount and email
   fields, and further still with a custom amount typed in. Measured live at 1440x900: the
   choose step's fields needed 644px against 493px available, 151px of forced scroll before a
   custom amount was even in the picture, 251px with one. None of these height cuts touch what
   the fields ask for or how they behave, only the padding and gaps around them. */
/* min-width:0 because <fieldset> carries a browser-default min-width:min-content that no amount
   of flex/min-width:0 further down the tree can override: the fieldset itself refuses to shrink
   narrower than its content's natural width, which is exactly what was still pushing the whole
   panel wider than a phone after the .gp-dd-val fix alone, found live 7 Sep 2026 re-measuring the
   same mobile overflow after that fix had already shipped and hadn't actually closed it. */
.gp-group{margin:0 0 10px;border:0;padding:0;min-width:0}
.gp-row{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.gp-row.four{grid-template-columns:repeat(4,1fr);gap:8px}
.gp-opt{position:relative;display:block}
.gp-opt input{position:absolute;opacity:0;width:0;height:0}
.gp-opt span{display:flex;align-items:center;justify-content:center;height:50px;border-radius:var(--r-sm);
  background:var(--tint);color:var(--tint-ink);font-family:'Poppins',Arial,sans-serif;font-weight:700;
  font-size:15px;cursor:pointer;text-align:center;padding:0 6px;
  transition:background .2s var(--sw),color .2s var(--sw)}
.gp-row.four .gp-opt span{height:46px;font-size:13.5px}
.gp-opt:hover span{background:#cfe4f6}
.gp-opt input:checked + span{background:var(--plan-blue);color:#fff}
.gp-opt input:focus-visible + span{outline:3px solid var(--yellow);outline-offset:3px}
.gp-select{width:100%;height:52px;border-radius:var(--r-sm);border:1.5px solid var(--grey);background:#fff;
  padding:0 44px 0 16px;font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:15px;
  color:var(--ink);cursor:pointer;appearance:none;font-size:16px;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230072CE' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 15px center;background-size:20px}
.gp-select:focus-visible{outline:3px solid var(--yellow);outline-offset:2px}
/* .tag was centring against .gp-other's FULL height (the "Your amount" label plus the input),
   not the input alone, because .gp-other{position:relative} was the tag's own positioning
   parent and the label sat inside the same box. top:50% of label+input together lands well
   above the input's own centre, which is exactly why CHF read as pinned near the top instead
   of centred like the number beside it, found live 7 Sep 2026. .gp-other-field wraps just the
   input and the tag, so 50% is 50% of the input alone. */
.gp-other{display:none;margin-top:8px}
.gp-other-field{position:relative}
.gp-other.show{display:block}
/* height alone does not centre an input's own text: Poppins' own line-height metrics run tall,
   so a plain <input height:58px> put "150" hard against the top of the box on Matthew's browser
   (not reproduced in a stock system font, which is why it slipped past an earlier check here).
   display:flex + align-items:center centres the value on the box regardless of the font's
   own metrics. */
.gp-other input{display:flex;align-items:center;width:100%;height:52px;border-radius:var(--r-sm);border:1.5px solid var(--grey);
  padding:0 62px 0 16px;font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:16px;color:var(--ink)}
/* No rule at all here meant the browser's own default (blue) focus ring, the exact
   inconsistency Matthew called out: "one can't be blue and one can't be yellow." */
.gp-other input:focus-visible{outline:3px solid var(--yellow);outline-offset:2px}
.gp-other .tag{position:absolute;right:16px;top:50%;transform:translateY(-50%);font-weight:700;
  font-size:14px;color:var(--grey);pointer-events:none}
.gp-impact{background:var(--paper-2);border-radius:var(--r);padding:12px 16px;margin:4px 0 14px;
  font-size:14.5px;line-height:1.4;color:var(--ink)}
.gp-impact .figtag{margin-top:7px;display:block}
/* Pinned inside the scroller: at 1300x700 the CTA sat 13px below the panel's own cut, with a
   30px radius making the truncation look like the end of the card. The gradient above it is not
   decoration: without it the pinned button simply lands on top of the caveat line and reads as
   an overlap bug rather than as a fixed control. */
.panel-give form{display:flex;flex-direction:column}
.gp-cta::before{content:"";position:absolute;left:0;right:0;bottom:100%;height:26px;
  background:linear-gradient(rgba(255,255,255,0),#fff);pointer-events:none}
.gp-cta{position:relative}
.gp-cta{position:sticky;bottom:0;display:flex;align-items:center;justify-content:center;gap:10px;width:100%;height:60px;
  border-radius:999px;background:var(--yellow);color:var(--ink);text-decoration:none;
  font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:16.5px;
  transition:transform .16s var(--sw),box-shadow .2s var(--sw)}
.gp-cta:hover{transform:translateY(-1px)}
.gp-cta:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}
.gp-cta svg{width:19px;height:19px}
.gp-trust{list-style:none;display:flex;flex-wrap:wrap;gap:6px 16px;margin:16px 0 0;padding:0}
.gp-trust li{display:flex;align-items:center;gap:6px;font-size:12.5px;font-weight:700;color:var(--grey)}
.gp-trust svg{width:15px;height:15px;flex:none;stroke:var(--plan-blue)}
.gp-note{font-size:12.5px;margin-top:12px}
/* SHARED-WITH-HOME BEGIN
   Everything between these markers is copied verbatim into the homepage's own stylesheet by
   build.py's sync_home(). The homepage keeps its own copy of the CSS because the two have
   diverged in about a dozen rules over the life of the concept and the homepage design is
   frozen, so a wholesale swap would move approved work. This block is the narrow channel for
   rules that MUST exist on both, and it is re-copied on every build. Put shared additions
   here, not elsewhere in this file. */

/* ── POPPINS, SELF-HOSTED ────────────────────────────────────────────────────────────────────
   Embedded rather than loaded from fonts.googleapis.com. The Google-hosted stylesheet opens a
   connection to Google in the United States and transmits every visitor's IP address before the
   cookie banner has even rendered, regardless of what they later choose. LG Munich I ruled that
   configuration unlawful (3 O 17493/20, January 2022) and awarded damages. The Foundation is
   Zurich-registered with European donors, and once it self-hosts it owns this exposure outright.

   Embedded as data URIs rather than linked because these pages are served from Blob at /d/<id>,
   where a relative path to a repo file does not resolve. Latin subset, two weights, 16KB total.
   Poppins is SIL Open Font License 1.1, so self-hosting is permitted. See fonts/LICENSE.txt. */
@font-face{font-family:'Poppins';font-style:normal;font-weight:600;font-display:swap;
  src:url(data:font/woff2;base64,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) format('woff2')}
@font-face{font-family:'Poppins';font-style:normal;font-weight:700;font-display:swap;
  src:url(data:font/woff2;base64,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) format('woff2')}


/* THE PENDING NOTE. Hidden until the CTA is pressed, revealed by :target alone, so it needs
   no JavaScript and survives the port to the locked platform. Yellow rule, not red: nothing
   is broken, the account simply is not connected yet. */
.gp-pending{display:none}
.gp-pending:target{display:block;margin-top:12px;padding:12px 14px;border-radius:var(--r-sm);
  background:var(--tint);border-left:4px solid var(--yellow);
  font-size:13px;line-height:1.5;color:var(--ink)}
.gp-pending:target b{font-weight:700}

/* Footer entries for pages that do not exist yet: exactly the rhythm of their neighbours, but
   plainly not clickable. They used to be href="#", which reads as a working link and then does
   nothing when pressed. The box comes from the shared .ft-col a.sm rule so the rows can never
   sit off the column; only what makes it non-interactive is stated here. */

/* The review chip's +/- glyph is a 26px button. The whole head already toggles, so a tap
   anywhere on the chip works, but the button is the keyboard target, so its hit area is
   extended to 44px as well. */
html body .ggfa-toggle{position:relative}
html body .ggfa-toggle::after{content:"";position:absolute;inset:-9px;border-radius:999px}
/* ── WIDTH ───────────────────────────────────────────────────────────────────────────────────
   Matthew, 11 August: "I think the width of the site needs to be responsive."

   He is right, and the reason was structural rather than a taste call: until now NOTHING in
   this stylesheet fired above 1200px. Every query was a max-width, so a 2240px monitor got the
   layout designed for 1201px with 460px of margin bolted on each side. A fixed 1320px is not a
   wide state, it is the absence of one.

   The shell is now one token used by the content column and by Plan's header bar together, so
   they can never drift apart again. It grows with the viewport and stops at 1680px: at 2240px
   the margins are 280px a side and read as a deliberate frame; at 1512px the column is 1391px,
   wider than the old fixed 1320; below 1200px nothing changes.

   It also fixes a live alignment fault: .ph-bar carried 18px of padding while .wrap carried up
   to 40px, so Plan's nav started as much as 22px left of the body content at every width above
   1000px, and the centred lockup was centred over nothing. One padding token, both elements. */
:root{ --wrap:min(1680px,92vw); --gutter:clamp(20px,3vw,48px) }
.wrap{max-width:var(--wrap);padding-inline:var(--gutter)}
.ph-bar{max-width:var(--wrap);padding-inline:var(--gutter)}
.pg-masthead h1{max-width:14em}

/* MEASURE. This was `section p:not(.cta-line):not(.band-copy p){max-width:42em}`, and :not()
   takes the specificity of its argument, so it computed to (0,2,3), sat at the bottom of the
   file, and silently overrode six earlier and more considered caps: the section intro at 38em,
   the card copy at 34em, the lead card at 30em, the pull-figure caption at 22em and the report
   note at 20em. A caption designed at 363px was rendering at 564px. That one line was most of
   the "everything is the same ribbon width" problem.
   :where() has zero specificity, so every component rule beats it and those measures come back.
   68ch is also nearer the readable 45-75 character band than 42em of Arial, which is about 84. */
:root{ --measure:68ch }
/* ══ TOKENS (spec 1.1, 5 Sep 2026). One sheet, and every object below draws from it. Inside
   SHARED-WITH-HOME on purpose: the homepage keeps its own copy of everything outside this region,
   so a token declared at 492 would never reach it. The needle '--r:16px' in sync_home proves the
   copy landed. --r on every object, --r-sm on small ones and documents, pills 999, circles 50%;
   nothing between 8 and 16, nothing below 8. Two shadows and no others. One hairline for every
   row separator. One 4px rule, at most once per section. A spacing scale so vertical rhythm is
   a number from a list, not a value chosen by eye. */
:root{
  --inset:14px; --r:16px; --r-sm:8px;
  --shadow-1:0 10px 24px rgba(10,42,67,.18);
  --shadow-2:0 24px 60px rgba(10,42,67,.16);
  --hairline:var(--keyline);
  --rule:4px solid var(--plan-blue);
  --s1:8px; --s2:14px; --s3:28px; --s4:40px; --s5:64px; --s6:clamp(56px,7vw,104px);
}
:where(section) :where(p){max-width:var(--measure)}
.legal{--measure:none}
.sec-intro{max-width:38em}
.img-band .band-copy{max-width:34em}
/* the three inline max-widths that used to sit in the markup. Inline styles cannot be
   overridden from a stylesheet, so on the locked platform, where added CSS is the only lever,
   each one was a block nobody could ever widen. */
.feature-points{max-width:46em}
.dd-checks{max-width:44em}
.ct-form{max-width:34em}

/* ── THE WIDE STATE ──────────────────────────────────────────────────────────────────────────
   Matthew: "On the right-hand side, you're having too much negative space in places that need
   to be fixed. For instance, What Can You Expect? is the questions and answers. You have a lot
   of negative space on the right. You need to make sure we're using or utilising space
   correctly, not just having dead space for the sake of having dead space."

   One breakpoint does all of it: 1200px, the first width where a heading rail plus a full
   reading measure fit side by side. Everything here is layout only, no new design language, and
   the pattern is the one already approved on the due-diligence cards.

   The principle, in his words: space bounded by a rule or a facing column is composition,
   space with nothing on the other side of it is a hole. */
/* Below 1200 the head stacks: eyebrow, 14, h2, 14, intro; body at 28 (spec 1.3). */
.sec-head .sec-eyebrow{margin:0}
.sec-head h2{margin:var(--s2) 0 0}
.sec-head .sec-intro{margin:var(--s2) 0 0}
.sec-body{margin-top:var(--s3)}
.sec-note{padding:var(--s5) 0}
/* 11 September 2026: a Section body is the one place on the site someone can drop WordPress's
   own List block in (see ggf_allowed_blocks() in inc/blocks.php). Left alone that renders in the
   browser's own bare default (a black dot, serif numerals, no relation to anything else on the
   page), which belongs to no other list here. This reuses the exact device .feature-points
   already uses elsewhere on the site (a hairline rule between rows, a small yellow mark), so a
   list added inside a Section still reads as part of this design rather than a different one. */
.sec-body :where(ul.wp-block-list,ol.wp-block-list){list-style:none;margin:16px 0;padding:0}
.sec-body :where(ul.wp-block-list,ol.wp-block-list)>li{position:relative;padding:10px 0 10px 30px;
  border-top:1px solid var(--line);font-size:15.5px;color:var(--ink);line-height:1.55}
.sec-body :where(ul.wp-block-list,ol.wp-block-list)>li:first-child{border-top:none}
.sec-body ul.wp-block-list>li::before{content:"";position:absolute;left:0;top:19px;width:14px;height:3px;background:var(--yellow)}
.sec-body ol.wp-block-list{counter-reset:sec-list}
.sec-body ol.wp-block-list>li{counter-increment:sec-list}
.sec-body ol.wp-block-list>li::before{content:counter(sec-list);position:absolute;left:0;top:11px;
  font-family:'Poppins',Arial,sans-serif;font-weight:700;color:var(--plan-blue);font-size:14px}
@media(min-width:1200px){
  /* 1. Every section heading: title left, intro right, instead of a stack with a void beside it.
        This is exactly what .dd-head already does, applied to the other thirty-odd sections. */
  /* Spec 1.3. align-items:START, not end: bottom-aligning the intro in a 7/4 grid opened the
     187, 156, 153, 143, 125, 94 and 81px holes Matthew photographed, because a tall intro pushed
     the whole row down and the h2 rose to meet it. Now eyebrow to h2 is 14, head to body 40, on
     every rail head at every width from 1200 up, and the intro sits level with the h2's first line. */
  .sec-head{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));
    column-gap:clamp(24px,2.4vw,40px);align-items:start;margin-bottom:0}
  .sec-head .sec-eyebrow{grid-column:1/span 7;grid-row:1;margin:0}
  .sec-head h2{grid-column:1/span 7;grid-row:2;margin:var(--s2) 0 0;max-width:none}
  .sec-head .sec-intro{grid-column:9/span 4;grid-row:2;align-self:start;padding-top:.35em;margin:0;max-width:none}
  .sec-body{margin-top:var(--s4)}
  /* 'bar': one per page, the deliberate departure from the rail. Eyebrow and h2 across the full
     measure, the intro under the h2 in cols 1 to 8. Only where the body is a full-width picture
     device or the page's one wide object. */
  .sec-head.is-bar .sec-eyebrow,.sec-head.is-bar h2{grid-column:1/span 12}
  .sec-head.is-bar h2{max-width:20em}
  .sec-head.is-bar .sec-intro{grid-column:1/span 8;grid-row:3;padding-top:0;margin-top:var(--s2);max-width:var(--measure)}
  /* 'note': a hairline across, eyebrow and h2 in cols 1 to 5, the paragraphs in cols 6 to 12. */
  .sec-note .wrap{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:clamp(24px,2.4vw,40px);
    border-top:1px solid var(--hairline);padding-top:var(--s4)}
  .sec-note .sec-head{grid-column:1/span 5;display:block;margin:0}
  .sec-note .sec-head h2{font-size:28px;margin-top:var(--s2)}
  .sec-note .sec-body{grid-column:6/span 7;margin-top:0;max-width:var(--measure)}

  /* 2. The questions. NOT stretched: an accordion at 1200px would put the chevron a metre from
        its question and run the answers to 150 characters. The block is the right width, the
        container was the wrong shape. Heading rail left, questions at their measure right. */
  .sec--split > .wrap{display:grid;grid-template-columns:minmax(18rem,1fr) minmax(0,44rem);
    column-gap:clamp(48px,5vw,110px);align-items:start}
  .sec--split .sec-head{display:block;margin-bottom:0}
  .sec--split .sec-head .sec-intro{max-width:none}
  .faq-ask{margin-top:28px;font-size:15px}
}
@media(min-width:1400px){
  .sec--split .sec-head{position:sticky;top:112px}  /* clears the mast: 14 + 80 + 18 */
}
.faq-ask{margin-top:28px;font-size:15px;color:var(--grey)}
.faq-ask a{color:var(--plan-blue);text-decoration:underline;text-decoration-color:var(--yellow);
  text-decoration-thickness:2px;text-underline-offset:3px}

/* 3. The process steps read as a track across the page, not a column down one third of it. */
@media(min-width:1200px){
  /* .sec-body scopes these, and that is not decoration: the base .steps, .fact-rows and
     .person rules are declared LATER in this file at the same specificity, so a bare .steps
     here would lose the cascade to a max-width:44em two hundred lines down and the track would
     silently stay a 748px column. Measured, not assumed. */
  .sec-body .steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));
    gap:clamp(24px,2.6vw,44px);max-width:none}
  /* 4. Definition rows run the full content width, so the space right of the answer is a table
        margin bounded by a hairline rather than an unexplained hole. */
  .sec-body .fact-rows{max-width:none}
  .sec-body .fact-rows>div{grid-template-columns:minmax(12rem,3fr) minmax(0,7fr);gap:8px clamp(26px,3vw,56px)}
  .sec-body .fact-rows dd{max-width:var(--measure)}
  /* 5. The board: a monogram beside the name, not above it in a 400px card holding two words. */

}
@keyframes drawline-x{from{transform:scaleX(0)}to{transform:scaleX(1)}}

/* ── CRAFT PASS, 11 August ────────────────────────────────────────────────────────────────────
   An independent graphic-design review of this sheet against brand.css. Every fix below stays
   inside the fixed palette, Poppins/Arial and the sanctioned shape set. */

/* 1. THE YELLOW MARKER. An inline background paints the font's content area, which in Poppins is
   1.4em, so on a heading set at 1.05 line-height the yellow block was 0.43em taller than its own
   line and cut roughly 18px into the lines above and below. The comment in brand.css claims the
   leading prevents this; the metrics say it cannot. Painting a fixed band instead decouples the
   marker from the font metrics, so it sits behind the words at any size and never touches its
   neighbours. Headings that carry one get the room they need. */
.hl{background:linear-gradient(var(--yellow),var(--yellow)) no-repeat;
  background-size:100% .92em;background-position:0 .30em;
  padding:0 .18em;margin:0 -.10em;color:var(--ink);
  box-shadow:none;-webkit-box-decoration-break:clone;box-decoration-break:clone}
h1:has(.hl),h2:has(.hl),h3:has(.hl){line-height:1.18}
/* THE DEVICE, 14 August. Matthew: "when you're highlighting words, you should be using that
   yellow squiggle line... if we want to highlight a word, we use the line underneath it
   instead. Let's cross-check first."
   Cross-checked, and the honest answer is that neither device is evidenced. The Brand Manual is
   not in this repo, and NEITHER the marker nor the underline appears anywhere on the live
   globalgirlsfoundation.org or plan-international.org. Our own record already files both as
   "decorative styling in our concept" pending a paid review. So there is nothing to contradict
   his preference, and the underline is the lower-risk of the two: it sits clear of the words
   rather than behind them, so it cannot cut into the line above, cannot swallow a descender,
   and raises no contrast question. Both devices stay defined; switching back is one word.
   The underline needs the same leading allowance the marker had, because it hangs below the
   baseline into the space the next line wants. */
/* the masthead used to run a SECOND device under the same class name: an inset shadow that sat
   entirely below the baseline, so the homepage got a highlighter and every inner page got a
   thick underline, both called .hl. One device now. */
.pg-masthead h1 .hl{background:linear-gradient(var(--yellow),var(--yellow)) no-repeat;
  background-size:100% .92em;background-position:0 .30em;padding:0 .18em;box-shadow:none}
/* white type over the yellow band measures 1.65:1, and the descender of the y in "money"
   sat inside it. The marker carries its own ink wherever the heading is reversed out. */
.pg-masthead--deep h1 .hl,.pg-masthead--deep h1 .hl *{color:var(--ink)}

/* 2. THE HERO'S HEIGHT. The header was changed from fixed to sticky, which puts it back in
   normal flow, but the hero kept min-height:100svh. So it began 100px down a 100svh box and its
   buttons started roughly 100px below the fold on first paint, at every size. On a fundraising
   homepage that is the entire cost of the hero. */
/* --hdr, scroll-padding and the hero's height now live in THE MAST block below (spec 2.1). */

/* 3. ANCHOR LANDINGS. scroll-padding-top insets the scrollport and scroll-margin-top expands the
   target: they ADD. Two rules of 116px and 104px meant every in-page link, including the menu's
   Questions and answers, landed the heading 120px to 160px below the header with a band of empty
   page above it. One mechanism, tied to the real header height. */
[id]{scroll-margin-top:0}

/* 4. FOCUS RINGS RESHAPED THE BUTTON. .btn:focus-visible is two classes and beat .btn's own
   999px radius, so tabbing snapped every pill into a soft rectangle and back. An outline already
   follows the element's radius; it never needed one of its own. */
.btn:focus-visible,.ph-logo:focus-visible,.np-minor a:focus-visible,footer.plan a:focus-visible{
  outline:3px solid var(--yellow);outline-offset:3px}

/* 5. THE FLAGSHIP CARD ANSWERED NOTHING ON HOVER. Its hover set the background to the colour it
   already was and the border to the colour it already was, so the two grey cards responded and
   the blue one, the one most meant to be clicked, did not. */
#mission .themes .cell{transition:background .2s var(--ease),border-color .2s var(--ease)}
#mission .themes .flag:hover{background:var(--plan-blue-dk);border-color:var(--plan-blue-dk)}

/* 6. CONTRAST. This sheet already records the finding once: .9 white on Plan Blue is 4.26:1 and
   fails AA, solid white passes. Two rules still did it, and 12.5px yellow on Plan Blue is 3.47:1,
   which is worse. The yellow stays as a mark rather than as type. */
.themes .flag p{color:#fff}
.next-b{color:#fff}
.next-k{color:#fff}
.next-k::before{content:"";display:inline-block;width:22px;height:3px;border-radius:999px;
  background:var(--yellow);margin-right:10px;vertical-align:middle}

/* 7. A HARD SQUARE SHADOW BEHIND A ROUNDED CARD. 6px offset, no blur, no radius of its own, so
   its corners poked out past the card's curve. It is the only hard-edged shadow in a system of
   soft ones, and it is the same fault Matthew already reported about squares behind a photo. */

/* 8. THE BAND COPY SAT ABOVE ITS OWN SCRIM BY ACCIDENT. Two rules on one selector left z-index
   at 1, the same as the gradient, so white text cleared the photograph only through tree order.
   That exact fault has shipped twice before. */
.img-band .band-copy{z-index:2}

/* 9. ONE KEYLINE TOKEN. Card borders were drawn in --grey, the same value as the copy inside
   them, so the box competed with the words. This value clears the 3:1 non-text guideline the
   sheet cites elsewhere while receding behind the text. */
:root{--keyline:#c2ccd3}
.dd-card,.gp-select,.gp-other input,.ph-searchform input,
.themes--cards .cell,.themes--cards .cell:last-child{border-color:var(--keyline)}
.faq summary::after{border-color:var(--keyline)}


/* THE LEGAL PAGES. A privacy policy is the one page a donor's adviser reads end to end, and it
   was a 760px column of running text alone in the middle of a 2240px window. The clauses each
   carry an h2 already, so a contents rail costs nothing to build and turns the empty third into
   the fastest way through a long document. */
.legal-toc{display:none}
.legal-sep{border:0;border-top:1px solid var(--line);margin:44px 0}
.legal-foot{margin-top:40px}
@media(min-width:1200px){
  .legal .wrap{display:grid;grid-template-columns:minmax(0,17rem) minmax(0,50rem);
    column-gap:clamp(48px,5vw,110px);justify-content:center;align-items:start}
  .legal-toc{display:block;position:sticky;top:calc(var(--hdr) + 24px);align-self:start}
  /* .legal .legal-toc h2, not .legal-toc h2: the clause rule .legal h2 is the same specificity
     and sits later in the file, so it was setting this label to 28px. */
  .legal .legal-toc h2{font-family:'Poppins',Arial,sans-serif;font-size:13px;font-weight:700;
    letter-spacing:.14em;text-transform:uppercase;color:var(--plan-blue);margin:0 0 12px;line-height:1.3}
  .legal-toc a{display:block;padding:6px 0;font-size:14.5px;line-height:1.4;color:var(--grey);
    text-decoration:none;border-left:2px solid var(--line);padding-left:14px}
  .legal-toc a:hover{color:var(--plan-blue);border-left-color:var(--yellow)}
  .legal-body{min-width:0}
}

/* ── THE FOOTER, SHARED WITH THE HOMEPAGE ────────────────────────────────────────────────────
   These are the footer rules as rebuilt on 11 August. They live inside the shared block because
   the homepage keeps its own copy of this stylesheet: its footer MARKUP is synced by build.py,
   so without these it rendered five columns of markup inside the old three-column grid and came
   out 1167px tall against 752 everywhere else. Same class of drift as the dead links, caught by
   measuring every page rather than the one in front of me. */
/* The homepage's own copy still carries the two-column footer wrap this structure replaced,
   which made .ft-grid a 948px grid item and collapsed all five columns to their minimums. The
   footer is one row of peers now, so the wrap is a plain block again. */
footer.plan .ft-main .wrap{display:block}
.ft-top{display:flex;align-items:flex-end;justify-content:flex-start;gap:clamp(28px,4vw,72px);flex-wrap:wrap;margin-bottom:38px}
.ft-grid{display:grid;grid-template-columns:repeat(4,minmax(140px,1fr)) minmax(300px,1.5fr);
  gap:clamp(22px,2.2vw,48px);padding:30px 0}
.ft-col h3{font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:17px;color:#fff;margin:0 0 12px}
.ft-col a{display:block;color:#fff}
.ft-col a.big{font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:clamp(17px,1.15vw,20px);
  line-height:1.35;padding:5px 0;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:5px}
.ft-col a.big:hover{text-decoration-thickness:2px}
.ft-col a.sm{font-size:15px;line-height:1.5;padding:5px 0;text-decoration:underline;text-underline-offset:3px}
.ft-col p{margin:0 0 8px;line-height:1.6;font-size:15px}
.ft-col p a{display:inline;text-decoration:underline;text-underline-offset:3px}
.ft-addr{font-size:14.5px}
footer.plan .ft-col a{padding:3px 0}
footer.plan .ft-grid{gap:clamp(22px,2.2vw,48px);margin-bottom:0}
footer.plan .ft-grid h3{margin-bottom:10px}
footer.plan .ft-rails-in{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(20px,2.4vw,48px);margin-top:22px;padding-top:20px;
  border-top:1px solid rgba(255,255,255,.28)}
.rail{min-width:0}
.rail span:not(.rail-h){font-size:14.5px;line-height:1.55;color:rgba(255,255,255,.94)}
.ft-legal{background:var(--plan-blue-dk);border-top:0;padding:15px 0}
@media(max-width:860px){ .ft-grid{grid-template-columns:1fr} footer.plan .ft-rails-in{grid-template-columns:1fr;gap:18px} }
@media(min-width:861px) and (max-width:1180px){
  footer.plan .ft-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  footer.plan .ft-grid .ft-news{grid-column:1 / -1}
  footer.plan .ft-grid .nl-pill{max-width:460px}
}

/* THE STORY. Matthew, 11 August: "you're still using placeholders for certain sections, like
   where you have the story. You need to put an actual story so they can understand what it
   looks like." So the section carries a written story now rather than a held-empty space, and
   the opening line is set as the pull quote the design was always shaped around. */
.feature-body .lede{font-family:'Poppins',Arial,sans-serif;font-weight:700;
  font-size:clamp(22px,1.9vw,28px);line-height:1.25;letter-spacing:-.015em;
  color:var(--plan-blue);margin-bottom:18px;max-width:16em}
.story-credit{
  font-size:14.5px;color:var(--grey);margin-top:18px;padding-top:14px;
  border-top:1px solid var(--keyline)}

/* ── THE MENU TOGGLE, SHARED WITH THE HOMEPAGE ───────────────────────────────────────────────
   Matthew, 11 August: the word Menu goes BESIDE the icon and to the right of it, in line, not
   below it. Done on the subpages the first time round, and missed on the homepage, because the
   header's styling lives outside this block while the header's MARKUP is synced into it. That
   is the third time the same seam has bitten, after the dead footer links and the footer grid,
   so the rule now lives here where both get it. */
.ph-menu{width:auto;height:100px;border:0;background:none;color:#fff;cursor:pointer;
  display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:11px;padding:0 8px 0 0}
.ph-menu .bars{flex:none}
.ph-menu span.lbl{font-family:Arial,Helvetica,sans-serif;font-size:16px;font-weight:700;line-height:1}
@media(max-width:1024px){ .ph-menu{width:auto;height:82px} }
@media(max-width:560px){ .ph-menu{width:auto;height:72px;gap:0} }

/* ── COOKIE CONSENT ──────────────────────────────────────────────────────────────────────────
   Part of the SITE, not the review tooling, so it is in the Foundation's own colours and it
   stays at launch. Everything pink comes off; this does not.

   Matthew, 14 August: "It just isn't designed right. There's nothing innovative about it...
   We need to be drawing attention, making sure that our donors are persons that see that we pay
   attention to detail."

   Fair. The first version was the default full-width grey slab every site has. This is built
   from the site's own devices instead of ignoring them: the 30px panel radius, the yellow
   circle that sits behind the mastheads, the yellow marker on one word of the heading, the same
   easing curve as the header panels, and the grid-rows collapse the navigation already uses. It
   is a card in the corner rather than a bar across the foot, so the page stays readable behind
   it and it reads as part of the design rather than as something bolted on.

   The compliance is in the layout as much as the script. Accept and Reject are the SAME
   component, identical in size, weight and colour, side by side: under the EU rules and the
   Swiss FADP refusing has to be as easy as accepting, and a pale or smaller reject is the single
   most commonly enforced dark pattern. There is no scrim, so it is not a cookie wall.          */
.ck{position:fixed;right:24px;bottom:24px;z-index:900;width:min(560px,calc(100vw - 48px))}
.ck[hidden]{display:none}
.ck-card{position:relative;background:#fff;border-radius:var(--r);padding:30px 32px 26px;
  box-shadow:0 26px 64px rgba(10,42,67,.26),0 2px 0 rgba(10,42,67,.04);
  animation:ckrise .55s var(--sw) both}
@keyframes ckrise{from{opacity:0;transform:translateY(26px) scale(.985)}to{opacity:1;transform:none}}
.ck-head h2{font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:clamp(21px,1.7vw,25px);
  line-height:1.2;letter-spacing:-.015em;color:var(--ink);margin:0 0 10px}
.ck-head p{margin:0;font-size:15px;line-height:1.6;color:var(--grey);max-width:46ch}

.ck-acts{display:flex;gap:12px;margin-top:20px}
/* Accept and Reject are indistinguishable except for the word on them. */
.ck-btn{flex:1 1 0;font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:15px;
  height:52px;padding:0 20px;border-radius:999px;cursor:pointer;white-space:nowrap;
  background:var(--plan-blue);color:#fff;border:2px solid var(--plan-blue);
  transition:transform .16s var(--sw),background .16s var(--sw)}
.ck-btn:hover{background:var(--plan-blue-dk);border-color:var(--plan-blue-dk);transform:translateY(-2px)}
.ck-btn:focus-visible,.ck-choose:focus-visible,.ck a:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}

.ck-choose{display:flex;align-items:center;gap:9px;margin-top:16px;padding:6px 0;
  background:none;border:0;cursor:pointer;font-family:'Poppins',Arial,sans-serif;
  font-weight:700;font-size:14.5px;color:var(--plan-blue)}
.ck-choose-t{text-decoration:underline;text-decoration-color:var(--yellow);
  text-decoration-thickness:2px;text-underline-offset:4px}
.ck-chev{width:9px;height:9px;border-right:2.5px solid currentColor;border-bottom:2.5px solid currentColor;
  transform:rotate(45deg) translateY(-2px);transition:transform .35s var(--sw)}
.ck.open .ck-chev{transform:rotate(-135deg) translateY(-2px)}

/* Collapses by grid rows: animates to the content's own height with no magic number. */
.ck-panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .42s var(--sw)}
.ck.open .ck-panel{grid-template-rows:1fr}
.ck-panel-in{overflow:hidden;min-height:0}
.ck-row{display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:15px 0;border-top:1px solid var(--keyline)}
.ck-row-t{min-width:0}
.ck-row h3{font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:15.5px;
  color:var(--ink);margin:0 0 3px}
.ck-row p{margin:0;font-size:13.5px;line-height:1.5;color:var(--grey)}
.ck-always{flex:none;font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:12.5px;
  color:var(--plan-blue);background:var(--tint);border-radius:999px;padding:7px 14px;white-space:nowrap}
/* a real checkbox drawn as a switch, so it stays keyboard reachable and correctly announced */
.ck-sw{flex:none;cursor:pointer;display:inline-flex}
.ck-sw input{position:absolute;opacity:0;width:1px;height:1px}
.ck-track{width:54px;height:31px;border-radius:999px;background:#fff;border:2px solid var(--grey);
  position:relative;transition:background .22s var(--sw),border-color .22s var(--sw)}
.ck-track::after{content:"";position:absolute;top:3px;left:3px;width:21px;height:21px;border-radius:50%;
  background:var(--grey);transition:transform .22s var(--sw),background .22s var(--sw)}
.ck-sw input:checked + .ck-track{background:var(--plan-blue);border-color:var(--plan-blue)}
.ck-sw input:checked + .ck-track::after{transform:translateX(23px);background:#fff}
.ck-sw input:focus-visible + .ck-track{outline:3px solid var(--yellow);outline-offset:3px}
/* the sentence that says what the switches currently mean */
.ck-state{margin:16px 0 0;font-family:Georgia,'Times New Roman',serif;font-style:italic;
  font-size:14px;color:var(--ink);border-left:3px solid var(--yellow);padding-left:12px}
.ck-save{width:100%;flex:none;margin-top:16px}
.ck-more{margin:14px 0 0;font-size:13.5px}
.ck-more a{color:var(--plan-blue);text-decoration:underline;text-decoration-color:var(--yellow);
  text-decoration-thickness:2px;text-underline-offset:3px}

@media(max-width:640px){
  .ck{left:12px;right:12px;bottom:12px;width:auto}
  .ck-card{padding:24px 20px 20px;border-radius:var(--r)}
  .ck-acts{flex-direction:column}
  .ck-row{flex-direction:row;align-items:flex-start}
}
@media(prefers-reduced-motion:reduce){
  .ck-card{animation:none}
  .ck-panel{transition:none}
}
@media print{.ck{display:none}}


/* THE HEADER SCRIM, shared with the homepage. It carried backdrop-filter:blur(3px), and the
   homepage had accumulated forty-one copies of the div, so the browser was compositing
   forty-one full-screen blurs: the page arrived late, flickered, and went blank on scroll.
   The duplicates are fixed at the source; the blur is gone here because the rule lives outside
   the shared region and the homepage would otherwise keep its own blurred copy, which is the
   fourth time that seam has bitten. A deeper scrim reads the same and costs nothing. */
.hdr-scrim{position:fixed;inset:0;background:rgba(12,16,20,.55);
  backdrop-filter:none;-webkit-backdrop-filter:none;
  opacity:0;pointer-events:none;z-index:75;transition:opacity .5s var(--sw)}
.hdr-scrim.on{opacity:1;pointer-events:auto}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   MOTION. Text, images and surfaces, 21 August.

   Matthew: "Add some transitions to text and images ... Transitions and these types of things
   you're using need to be delicate. These are girls we're talking about."

   Three designers worked this in parallel (type, photography, system) and returned three
   incompatible stylesheets. This is the reconciliation, and the decisions that resolve them
   are recorded where they were made, because each one was contested.

   THE INVARIANT, AND THE ONE THING NOT TO BREAK.
   NOTHING MAY HIDE AN ELEMENT EXCEPT UNDER html.m-ready. motion.js adds that class as its first
   act, so a hidden state can only exist while the thing that removes it is running. Blocked
   script, 404, Content-Security-Policy refusal, parse error and thrown exception all then render
   the whole page, unanimated. This was learned the expensive way: one ungated opacity:0 left 175
   elements invisible across eight pages. If you add a rule that hides, gate it, and if you add a
   `both`-filled animation whose from-keyframe is invisible, gate that too.

   THE TWO HARD RULES, both scoped to ENTRANCES: no entrance travels further than 16px, and no
   entrance takes longer than 700ms. The scoping is not a get-out. A panel the reader has just
   opened by hand is not arrival motion, and a photograph resolving its crop while remaining
   legible throughout is not an entrance either. Stated without that scope, as it was, the
   sentence was simply untrue of the file it introduced.
   Past 16px the eye follows the journey; under it you register only the arrival. That is the
   whole distance between "delicate" and a product launch. Note what this does to what was
   already here: .reveal moved 20px, and now moves 10px. Asked to add motion everywhere, the
   answer was to make the existing motion quieter.

   THE DIVISION OF PROPERTIES, so three sets of rules never fight over one value:
     entrances    -> translate     (this file)
     interactions -> transform     (hover and focus, below)
     photographs  -> transform: scale on the image element, never on its frame
   translate and transform compose, so a card can be hovered mid-entrance and neither gesture
   cancels the other. This is why every entrance below uses `translate` and not translateY().

   ON PHOTOGRAPHS, which is the part of this brief that actually matters. Every photograph on
   this site is a girl. A photograph is never moved: the frame moves, and the image inside it
   is allowed exactly one gesture, releasing from a 3.5% overscale and decelerating to a stop.
   No face translates, nothing loops, nothing parallaxes, and no photograph answers the cursor.
   The overscale was 7%, which on a 4:5 portrait is a visible push-in on a child's face.

   NO-JS SAFETY. Three independent layers, any one of which prevents a blank page. Layer 1:
   html.no-js shows everything with no motion at all, needing no file to load. This was a live
   bug, not a precaution: .reveal sets opacity 0 and only JavaScript ever restored it, so with
   JS disabled every animated element on the site was invisible. Layer 2: the scroll-driven
   lane below, whose hidden state exists only as the backwards fill of a running animation and
   so cannot outlive it. Layer 3: motion.js, which carries its own rAF pass and a 3s failsafe.
   ══════════════════════════════════════════════════════════════════════════════════════════ */

:root{
  --m-hover:180ms;    /* pointer or keyboard feedback on a control. Must feel instant.       */
  --m-state:300ms;    /* a control changing state: chevron, keyline, accordion answer.       */
  --m-enter:640ms;    /* body copy and list rows arriving.                                   */
  --m-enter-lg:700ms; /* headings and display figures. THE CEILING. Nothing exceeds it.      */
  --m-settle:1100ms;  /* a photograph coming to rest. The one long duration, and it is not
                         an entrance: the image is visible throughout, only its crop resolves. */

  --m-rise:14px;      /* surfaces: cards, panels, blocks.                                    */
  --m-rise-lg:10px;   /* headings. About a quarter of the leading at every size on this site,
                         which is where motion reads as weight settling rather than an object
                         crossing the page. 20px on a 15.5px list row was a full line of travel. */
  --m-rise-sm:7px;    /* body copy, list rows, captions, and any surface wider than ~600px:
                         a 1200px panel rising 14px reads as a shove, not a settle.           */

  --m-stagger:90ms;   /* one beat between siblings, time-based lane.                          */
  --m-step:8%;        /* the same beat, as a share of the element's own entry.                */
  --m-range:75%;      /* entrance length, as a share of entry. With the index capped at 3 the
                         latest anything can finish is 99% of its own entry, i.e. just before
                         it is fully in view. That cap is the point: see THE STAGGER HOLE.    */
  --m-i:0;            /* sibling index. Set structurally, never authored by hand.             */
  --m-over:1.035;     /* photographic overscale. 3.5%, not 7%.                                */
  --m-failsafe:4s;
}

/* THE CURVE is the existing --ease, cubic-bezier(.2,.7,.2,1): front-loaded with a long settle,
   and with no control point above 1 it physically cannot overshoot or bounce. --sw is the UI
   curve, for accordions and hovers, and is too snappy for prose. No third curve is introduced,
   and there is deliberately no spring, no back and no bounce anywhere in this system.

   THE FADE completes at 62% of the animation rather than riding a second curve, so the words
   are legible while the last two or three pixels of travel resolve. That is the difference
   between motion that reads as settling and motion that reads as waiting, and it also means
   partial progress degrades to slightly light, never to blank. */
@keyframes ggf-rise{ from{opacity:0;translate:0 var(--m-d,10px)} 62%{opacity:1} to{opacity:1;translate:none} }
@keyframes ggf-settle{ to{opacity:1;translate:none} }

/* Arrival progress, 0 to 1, inherited. The initial value IS the resting state, so a browser that
   does not register it computes scale(1) and needs no fallback path. This exists because
   motion.js reveals every .reveal after 3 seconds as a safety net, which means a photograph
   below the fold discharges its settle invisibly. Tying the settle to scroll position instead
   means the gesture happens when the reader arrives at the picture, which is the only moment it
   was ever for. */
@property --m-p{ syntax:"<number>"; inherits:true; initial-value:1 }
@keyframes ggf-prog{ from{--m-p:0} to{--m-p:1} }

/* ── THE SIBLING INDEX ──────────────────────────────────────────────────────────────────────
   The most important technical requirement on this project: staff will add content in
   WordPress and will not add classes. So sequence comes from POSITION. One index, read by both
   the time-based lane (transition-delay) and the scroll-driven lane (animation-range).
   Capped at six: a seventh item waiting half a second to appear is a queue, not a composition. */
.reveal:nth-child(1){--m-i:0} .reveal:nth-child(2){--m-i:1} .reveal:nth-child(3){--m-i:2}
.reveal:nth-child(4){--m-i:3} .reveal:nth-child(n+5){--m-i:3}

/* Children of a known group that carry no class of their own: list rows, grid cells. Explicit
   on purpose: indexing every element on the page would put six universal selectors into style
   recalc for nothing. To give a new component a stagger, add its container here and nothing else. */
:where(.steps,.lay-register,.principles,.themes,.fact-rows,.stats,.trust-grid)>*:nth-child(1){--m-i:0}
:where(.steps,.lay-register,.principles,.themes,.fact-rows,.stats,.trust-grid)>*:nth-child(2){--m-i:1}
:where(.steps,.lay-register,.principles,.themes,.fact-rows,.stats,.trust-grid)>*:nth-child(3){--m-i:2}
:where(.steps,.lay-register,.principles,.themes,.fact-rows,.stats,.trust-grid)>*:nth-child(4){--m-i:3}
:where(.steps,.lay-register,.principles,.themes,.fact-rows,.stats,.trust-grid)>*:nth-child(n+5){--m-i:3}

/* The legacy delay classes still win where a human put one deliberately, because they are
   (0,2,0) and land after the index above. They now feed the same variable instead of setting
   their own transition-delay, so there is one mechanism rather than two fighting. */
.reveal.d1{--m-i:1} .reveal.d2{--m-i:2} .reveal.d3{--m-i:3} .reveal.d4{--m-i:3}

/* ── DISTANCE, BY WHAT THE THING IS ─────────────────────────────────────────────────────────
   One distance cannot serve a 74px headline and a 15.5px list row. */
.reveal{--m-d:var(--m-rise)}
:where(h1,h2,h3,h4,.sec-eyebrow,.eyebrow,.sec-intro,.lead).reveal{--m-d:var(--m-rise-lg)}
:where(p,li,.note,.figtag,.story-credit).reveal{--m-d:var(--m-rise-sm)}
:where(.next-link,.img-band,.cta-card,.feature,.dd-card,.next-band).reveal{--m-d:var(--m-rise-sm)}

/* ── LANE 1: THE EXISTING REVEAL, RETUNED ───────────────────────────────────────────────────
   brand.css moves .reveal 20px on transform. This moves it 10px on translate, freeing transform
   for hover. No hidden state is added here that was not already there. */
/* HIDE ON A POSITIVE SIGNAL, NEVER ON THE ABSENCE OF A NEGATIVE ONE.
   brand.css hides .reveal unconditionally: a rule that assumes a script will arrive to undo it.
   With the text lane driven entirely by motion.js that assumption stopped being free. One failed
   request emptied EIGHT OF TEN PAGES, 175 elements stuck invisible, reproduced both by blocking
   the file and by a real Content-Security-Policy header, which is what a corporate network does
   to an unfamiliar domain. html.no-js does not help: the inline head script flips no-js to js as
   the page parses, whether or not motion.js ever arrives, so that hatch is shut before the
   failure happens.
   So the base state is VISIBLE and at rest, and hidden is re-applied only under html.m-ready,
   which motion.js sets as its first act. Blocked, 404, CSP, parse error: each now renders the
   whole page with no motion, the correct degradation. Same discipline as the photographs. */
.reveal{opacity:1;transform:none;translate:none;
  transition:opacity var(--m-enter-lg) var(--ease),translate var(--m-enter-lg) var(--ease);
  transition-delay:calc(var(--m-i,0) * var(--m-stagger))}
/* A RESCUE IS NOT AN ENTRANCE. When m-ready is withdrawn, by the catch or by the watchdog,
   the content must appear AT ONCE rather than fade over 700ms. Two reasons: the reader has
   already been waiting for a script that failed, and a transition does not advance in a tab
   that is not being painted, so a rescued background tab would hold the fade indefinitely
   and only resolve when the reader returned to it. Snap instead. */
html:not(.m-ready) :is(.reveal,.m-fx){transition:none!important;animation:none!important}
html.m-ready .reveal{opacity:0;translate:0 var(--m-d)}
/* (0,3,1), so it beats html.m-ready .reveal at (0,2,1). */
html.m-ready .reveal.in{opacity:1;translate:none;transform:none}
/* (0,2,0) so it supersedes brand.css's .reveal.d1-.d4 transition-delay, which is the same
   specificity but earlier in the cascade. Without this the stagger silently does nothing. */
.reveal.d1,.reveal.d2,.reveal.d3,.reveal.d4{transition-delay:calc(var(--m-i,0) * var(--m-stagger))}

/* ── THE COVERAGE LANE ───────────────────────────────────────────────────────────────────────
   The class motion.js adds to copy that carries none of its own. This is the coverage the brief
   asked for: why-girls had 27 reveal classes against 22 headings and 48 paragraphs, so about
   half of every page had no motion at all.
   It is added by script and never written into the markup, and that is the safety property: an
   element only becomes hidden AFTER the script that will reveal it is already running. A
   stylesheet that ships opacity:0 cannot promise that, which is why the .reveal lane above needs
   an html.no-js escape hatch and this one does not.
   Driven by the clock, not the scroll. A scroll range is proportional to the element's own
   height, so a 21px eyebrow finished its fade in eight pixels of scrolling, under a tenth of one
   wheel notch: those headings blinked on rather than faded in. 640ms is 640ms at any speed. */
.m-fx{--m-d:var(--m-rise-sm);
  transition:opacity var(--m-enter) var(--ease),translate var(--m-enter) var(--ease);
  transition-delay:calc(var(--m-i,0) * var(--m-stagger))}
:where(h1,h2,h3,h4).m-fx{--m-d:var(--m-rise-lg)}
/* Gated like everything else. m-fx is added by script, so it is already safe when the script
   never runs; the gap was the script running, tagging, and THEN failing, where withdrawing
   m-ready could not rescue elements that were already hidden by an ungated rule. */
html.m-ready .m-fx{opacity:0;translate:0 var(--m-d)}
html.m-ready .m-fx.in{opacity:1;translate:none}

/* ── LANE 2: SCROLL-DRIVEN, NO JAVASCRIPT ───────────────────────────────────────────────────
   THE STAGGER HOLE, and why every range below is "entry" and never "cover".
   A "cover" range is measured against the VIEWPORT: element height plus viewport height. An
   "entry" range is measured against the ELEMENT: it starts when the element begins entering and
   finishes exactly when it is fully in view.
   Cover reads better on paper, because a short caption and a tall block then get comparable
   travel. It is also wrong, and it shipped: a 59px row on the giving page reached full
   visibility 59px after appearing, but its staggered cover range did not START until 153px, so
   the row sat fully on screen, at opacity zero, with clear space beneath it, for about 94 pixels
   of scrolling. A blank hole in a list, on the page where donors choose how to give.
   Entry cannot do that, by construction. The cost is that a very short element gets a short
   fade, and that is the right trade: a quick fade is a style opinion, a blank row is a defect.
   The index is capped at 3 so the latest possible finish is 99% of entry. */


/* ── PHOTOGRAPHS ────────────────────────────────────────────────────────────────────────────
   transform-origin 50% 42%, not 50% 50%: faces sit above centre in every photograph in the IMG
   map, so settling toward the upper middle means the face is the part that does NOT move and the
   edges come in around it.
   figure and .wp-block-image are here deliberately. They are what the WordPress image block
   emits by itself, so a photograph dropped into a page months from now inherits this with nobody
   doing anything.
   .duo is deliberately ABSENT: it runs mix-blend-mode: multiply, which forces the browser to
   re-composite the backdrop every frame, and animating its grayscale would look like the colour
   draining out of a child's face.

   THE RESTING STATE IS scale(1), AND EVERY OVERSCALE IS GATED ON html.m-ready.
   This is the shape of a bug worth not repeating. The pre-state here is a 3.5% overscale, and an
   overscale that never gets released does not fail quietly the way a fade does: the photograph
   renders 12px larger than its frame, loses its rounded corners, and spills over the device
   behind it. That shipped, because the no-JS guard was written to stop TEXT going blank and
   nobody asked what it did to the pictures. Gating on a class that motion.js adds as its first
   act means the overscale cannot exist unless the thing that removes it is already running:
   script disabled, script 404s, script throws on an old engine, all resolve to scale(1).

   The two lanes below are mutually exclusive by @supports, so they can never fight over
   specificity. That was the second half of the same bug: the pre-state (0,3,1) was silently
   beating the scroll-driven value (0,1,1), so on Chrome the smooth settle was being overridden
   by the very rule it was meant to replace. */
:is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image)>img,
:is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image)>picture>img{transform-origin:50% 42%}

/* LANE A: no scroll-driven animations (Safari before 26, Firefox). A transition, released when
   the observer says a human has actually reached the picture. */
@supports not (animation-timeline:view()){
  html.m-ready :is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image)>img,
  html.m-ready :is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image)>picture>img{transition:transform var(--m-settle) var(--sw)}
  /* transition:none on the PRE-STATE, and this is the whole trick. The transition lives on
     the base rule above, so without this the arrival of html.m-ready starts a 1.1s
     transition INTO the overscale. The image then creeps toward 1.035 and gets cancelled
     a frame or two later when `seen` lands, so it never reaches the pre-state and has no
     distance to settle from. Snap into the overscale, ease out of it. */
  html.m-ready .reveal:not(.seen) :is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image)>img,
  html.m-ready .reveal:not(.seen) :is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image)>picture>img,
  html.m-ready :is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image).reveal:not(.seen)>img,
  html.m-ready :is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image).reveal:not(.seen)>picture>img{
    transform:scale(var(--m-over));transition:none}
}

/* ── PHOTOGRAPHS, PACED BY THE SCROLL ────────────────────────────────────────────────────────
   The one place a scroll-driven animation is right rather than merely available: a crop
   resolving as the reader approaches the picture IS arrival, so the reader's own movement should
   pace it. Text is the opposite case and is driven from motion.js on a clock; the reasoning is
   written out at the top of that file.
   This sits AFTER the transition above deliberately. That ordering was a live bug: the
   `transition:none` inside this block was overridden by the plain `transition:transform
   var(--m-settle)` that followed it at equal specificity, so a scroll timeline set a target and
   a 1.1s transition chased it, and a photograph of a child kept moving for a further second
   after the reader had stopped. One mechanism drives the crop now. */
@supports (animation-timeline:view()){
  /* The frame publishes its own arrival as an inherited number its children read. No stagger
     offset: a picture is one object and does not queue. */
  /* Gated on m-ready like everything else that hides. A `both` fill holds the from-keyframe,
     opacity 0, while the timeline sits at zero progress, so without this gate a blocked script
     left the band and the story photograph relying on a scroll timeline to un-hide them. That
     may well work, but "may well" is not the standard for whether a photograph appears. With no
     script the frames simply render, at full opacity and true size, and do not move. */
  html.m-ready :is(.mh-img,.img-band,.feature-media).reveal{
    animation:ggf-rise var(--m-enter-lg) var(--ease) both, ggf-prog var(--m-enter-lg) var(--sw) both;
    animation-timeline:view(),view();
    /* The photograph runs longer than the words beside it: 90% rather than 75%, so the crop is
       still resolving while the reader can see the whole picture, and it eases to a stop
       rather than halting at constant velocity. A linear crop resolve reads mechanical, and
       it is the one shape that should never be applied to a photograph of a child. */
    animation-range:entry 0% entry var(--m-range), entry 0% entry 90%}

  :is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image)>img,
  :is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image)>picture>img{
    transition:none;
    transform:scale(calc(1 + (1 - var(--m-p,1)) * (var(--m-over,1.035) - 1)))}

  /* Above the fold, an entry range is already spent before the first frame is painted, so a
     masthead portrait arrives finished, which is exactly how it shipped: no fade, no settle, on
     the first photograph of a girl a visitor sees. Stopping the timeline is only half the fix,
     though. It also has to be handed back to the observer, or the picture simply never moves. */
  .pg-masthead .mh-img{animation:none}
  html.m-ready .pg-masthead .mh-img>img{transform:scale(var(--m-over));transition:none}
  html.m-ready .pg-masthead .mh-img.seen>img{transform:none;
    transition:transform var(--m-settle) var(--sw)}
}


/* ── ABOVE THE FOLD ─────────────────────────────────────────────────────────────────────────
   A scroll-driven entrance is meaningless for something already on screen at load: its range is
   already spent, so it renders finished. And the masthead's three lines carry a hard-coded
   `in`, which renders them at their final state too. So the first thing a visitor sees has no
   entrance at all, on any browser.
   These get the one thing that needs no scroll and no script: a plain time-based animation.
   It is also the safest kind there is, because it runs to completion whether or not anything
   else on the page loads. Eyebrow, headline, standfirst, 90ms apart. */
/* Gated, because a `both`-filled animation whose from-keyframe is opacity 0 IS a hidden state,
   which is precisely what the invariant at the top of this block warns about. It survived
   because a time-based animation completes on its own in 700ms and so LOOKS safe: with the
   script blocked these three lines still appeared. The exception is a tab that is not being
   painted, where the animation never advances and the `both` fill holds the invisible
   keyframe indefinitely. Caught by withdrawing m-ready in a hidden tab and finding the
   masthead headline still at opacity 0. Ungated hidden states have now caused this same
   class of bug four times; this is the last one on the page. */
html.m-ready .pg-masthead .mh-copy>*{--m-d:var(--m-rise-lg);
  animation:ggf-rise var(--m-enter-lg) var(--ease) both}
html.m-ready .pg-masthead .mh-copy>*:nth-child(2){animation-delay:var(--m-stagger)}
html.m-ready .pg-masthead .mh-copy>*:nth-child(3){animation-delay:calc(var(--m-stagger) * 2)}
/* the .reveal transition would fight the animation for the same two properties */
.pg-masthead .mh-copy>.reveal{transition:none}

html.m-ready .hero .wrap>.reveal>*{--m-d:var(--m-rise-lg);
  animation:ggf-rise var(--m-enter-lg) var(--ease) both}
html.m-ready .hero .wrap>.reveal>*:nth-child(2){animation-delay:var(--m-stagger)}
html.m-ready .hero .wrap>.reveal>*:nth-child(3){animation-delay:calc(var(--m-stagger) * 2)}
html.m-ready .hero .wrap>.reveal>*:nth-child(n+4){animation-delay:calc(var(--m-stagger) * 3)}

/* ── SURFACES, HOVER AND FOCUS ──────────────────────────────────────────────────────────────
   Every rule here fires on :focus-visible as well as :hover. A keyboard user currently gets an
   outline and none of the movement, which means the site answers a mouse and merely tolerates
   a keyboard.
   Cards that are regions rather than controls get a keyline only: no lift, no shadow. Three of
   the four due-diligence cards are not clickable, and a card that rises under the cursor
   promises a click it cannot honour. */
/* LONGHANDS, NOT THE SHORTHAND, AND THE REASON MATTERS.
   `transition:` resets the whole property, so these hover rules were silently deleting the
   entrance transition from every element they touched: 49 surfaces across all eight pages,
   including all four due-diligence cards, the three mission cards, the six board portraits, the
   principles, and the next-page panel on every page. Those elements went from opacity 0 to 1 in
   a single frame. They popped. They are the largest surfaces on the site and the ones a reader
   looks at first, and stopping exactly that was the point of this work.
   The delay is listed per property deliberately: an ENTRANCE is staggered by position, but a
   HOVER must never be. One shorthand would have made a card wait up to 270ms for the cursor. */
#mission .themes .cell,.themes--cards .cell,.dd-card,.principles .pr{
  transition-property:opacity,translate,background-color,border-color;
  transition-duration:var(--m-enter),var(--m-enter),var(--m-state),var(--m-state);
  transition-timing-function:var(--ease),var(--ease),var(--sw),var(--sw);
  transition-delay:calc(var(--m-i,0) * var(--m-stagger)),calc(var(--m-i,0) * var(--m-stagger)),0s,0s}
.fact-rows>div,.dd-checks li,.dd-route li,.feature-points li{
  transition-property:opacity,translate,border-color;
  transition-duration:var(--m-enter),var(--m-enter),var(--m-state);
  transition-timing-function:var(--ease),var(--ease),var(--sw);
  transition-delay:calc(var(--m-i,0) * var(--m-stagger)),calc(var(--m-i,0) * var(--m-stagger)),0s}
/* Restated at (0,2,0) or higher so the legacy .d1-.d4 delay rule cannot flatten these back to
   a single value. If it did, background-color would inherit the entrance stagger and a card
   would wait up to 270ms before answering the cursor. Harmless the day this was written,
   because nothing staggered has a hover response, and a trap the day something does. */
#mission .themes .cell.reveal,.themes--cards .cell.reveal,.dd-card.reveal,
.principles .pr.reveal{
  transition-delay:calc(var(--m-i,0) * var(--m-stagger)),calc(var(--m-i,0) * var(--m-stagger)),0s,0s}
.fact-rows>div.reveal,.dd-checks li.reveal,.dd-route li.reveal,.feature-points li.reveal,
.next-link.reveal{
  transition-delay:calc(var(--m-i,0) * var(--m-stagger)),calc(var(--m-i,0) * var(--m-stagger)),0s}

.next-link{
  transition-property:opacity,translate,background-color;
  transition-duration:var(--m-enter),var(--m-enter),var(--m-state);
  transition-timing-function:var(--ease),var(--ease),var(--sw);
  transition-delay:calc(var(--m-i,0) * var(--m-stagger)),calc(var(--m-i,0) * var(--m-stagger)),0s}
.next-t svg{transition:transform var(--m-hover) var(--sw)}
.next-link:hover .next-t svg,.next-link:focus-visible .next-t svg{transform:translateX(6px)}

.btn{transition:transform var(--m-hover) var(--sw),background-color var(--m-hover) var(--sw),
  border-color var(--m-hover) var(--sw),box-shadow var(--m-hover) var(--sw)}
.btn svg{transition:transform var(--m-hover) var(--sw)}
/* Both states, deliberately. Until now only :focus-visible was declared, so the transition
   above had nothing to animate for a mouse user and the "press back into the page" on :active
   had no lift to press back from. */
.btn:hover,.btn:focus-visible{transform:translateY(-2px)}
.btn:hover svg,.btn:focus-visible svg{transform:translateX(4px)}
/* a button that presses back into the page is the most book-like gesture in the system */
.btn:active{transform:translateY(0);transition-duration:90ms}
.dd-link svg{transition:transform var(--m-hover) var(--sw)}
.dd-link:hover svg,.dd-link:focus-visible svg{transform:translateX(4px)}

/* Links in running copy took the browser default focus ring, so a keyboard reader got Chrome
   blue in the middle of a Plan Blue page. The yellow ring was scoped to buttons, the logo and
   the menu; this catches everything else. */
.sec-body a:focus-visible,.sec-head a:focus-visible,.feature-body a:focus-visible{
  outline:3px solid var(--yellow);outline-offset:2px}

/* The newsletter email field was the single focusable control on the site with no visible focus
   state at all: identical to blur except for the caret. 38 other tab stops get the yellow ring. */
#nl-email:focus-visible{outline:3px solid var(--yellow);outline-offset:2px}

/* A FIX, not a retune. This row transitions padding-left on hover, which runs a layout pass on
   a list of twelve rows for every frame of every hover and drags the row's own hairline
   sideways with it. Same reward, no layout: the arrow walks and the label underlines. */
.np-item{transition:color var(--m-hover) var(--sw)}
.np-item:hover,.np-item:focus-visible{padding-left:0;
  text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:6px}
.np-item::after{transition:transform var(--m-hover) var(--sw),opacity var(--m-hover) var(--sw)}
.np-item:hover::after,.np-item:focus-visible::after{transform:translateX(6px);opacity:1}

/* THE ACCORDION. No height animation ships: no sizing property is animated anywhere in this
   system, and this is the one project where that class of cost has already taken the page down.
   The box opens instantly and the ANSWER settles in. @starting-style means the pre-state exists
   for exactly one frame at open time and can never become a resting state, so this construction
   is structurally incapable of hiding content and needs no failsafe.
   The honest limitation, stated rather than hidden: closing does not animate, because <details>
   removes its own content from the box tree. A CSS-only accordion closes instantly. */
.faq .a{transition:opacity var(--m-state) var(--ease),translate var(--m-state) var(--ease)}
@starting-style{.faq[open] .a{opacity:0;translate:0 6px}}
.faq summary{transition:color var(--m-hover) var(--sw)}
.faq summary::after{transition:transform var(--m-state) var(--sw),background-color var(--m-hover) var(--sw)}

/* ── LAYER 1 OF THE NO-JS GUARANTEE ─────────────────────────────────────────────────────────
   build.py ships <html class="no-js"> and an inline head script rewrites it to "js". No script,
   no rewrite, and this shows everything with no motion at all. It needs no file to load and no
   observer to fire. This was a live bug: without it, JavaScript disabled meant every animated
   element on the site stayed at opacity 0 forever. */
/* .m-fx needs no entry here: it is only ever added by the script that reveals it. */
html.no-js .reveal,
html.no-js :where(.steps,.lay-register,.principles,.themes,.fact-rows,.stats,.trust-grid)>*,
html.no-js .feature-body>*,html.no-js footer.plan :where(.ft-strap,.ft-col,.rail,.ft-legal p){
  opacity:1;translate:none;transform:none;animation:none;transition:none}
/* Layer 3, for an old browser AND a missing motion.js: a zero-length animation delayed 4s
   forces every reveal visible, mirroring motion.js's own 3s net so JS wins the race whenever
   JS is alive. Scoped so it cannot clobber the scroll-driven lane on browsers that have it. */
@supports not (animation-timeline:view()){
  .reveal{animation:ggf-settle 1ms linear var(--m-failsafe) forwards}
}

/* ── REDUCED MOTION ─────────────────────────────────────────────────────────────────────────
   Everything off, everything visible. The keyframes are redefined rather than restating forty
   selectors and trusting that none was missed: a later @keyframes of the same name wins
   outright, so this cannot be partially applied.
   Note what is deliberately NOT here: a blanket opacity:1 on descendants. The giving panel and
   the menu panel are held CLOSED with opacity:0, and a blunt reset would leave a reduced-motion
   reader with the donation dialog permanently open over the page. */
@media (prefers-reduced-motion:reduce){
  @keyframes ggf-rise{ from{opacity:1;translate:none} to{opacity:1;translate:none} }
  /* !important throughout: the distance rules above are (0,2,0) and would otherwise outrank
     this reset and leave the wide surfaces sitting permanently 7px out of position. */
  .reveal,.m-fx,
  :where(.steps,.lay-register,.principles,.themes,.fact-rows,.stats,.trust-grid)>*,
  .feature-body>*,footer.plan :where(.ft-strap,.ft-col,.rail,.ft-legal p){
    animation:none!important;transition:none!important;
    opacity:1!important;translate:none!important;transform:none!important}
  :is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image)>img,
  :is(.mh-img,.fm-clip,.feature-media,.img-band,figure,.wp-block-image)>picture>img{
    transition:none!important;transform:none!important}
  .pg-masthead .mh-copy>*,.hero .wrap>.reveal>*{animation:none!important;opacity:1!important;translate:none!important}
  .btn,.btn svg,.dd-link svg,.faq summary,.faq summary::after,.faq .a,.np-item,.np-item::after,
  .next-link,.next-t svg,.dd-card,.principles .pr,.fact-rows>div,
  #mission .themes .cell,.themes--cards .cell{transition:none!important}
  .btn:hover,.btn:focus-visible,.btn:active{transform:none}
}

/* PRINT. Defensive rather than corrective: a view() timeline is inactive in paged media, so the
   base style already applies and the pages do print. Tested against a control, byte-identical
   PDFs. This guards the case anyway, because nothing should animate on paper and the cost of
   being wrong is a donor's adviser holding a blank sheet. */
@media print{
  @keyframes ggf-rise{ from{opacity:1;translate:none} to{opacity:1;translate:none} }
  .reveal,.reveal *{animation:none!important;opacity:1!important;translate:none!important;transform:none!important}
}


/* ══════════════════════════════════════════════════════════════════════════════════════════
   HOMEPAGE PARITY. Rules that MUST reach v7/index.html, kept inside the shared region.

   The homepage keeps its own copy of the stylesheet, and only this marked region is copied into
   it. That seam has now produced the same class of bug six times, and this last one was the
   worst: two fixes landed in the shared file, were verified, were reported as done, and never
   reached the one page the client opens first. The header fix even carries a comment naming the
   width the Managing Director would open it at, and it was live everywhere except there.
   Anything fixed for the whole site belongs in this block, not next to the component it edits.
   build.py refuses to build if any of these fail to reach the homepage.
   ══════════════════════════════════════════════════════════════════════════════════════════ */

/* A footer column stuck at its content width, clipping the newsletter strapline and cutting the
   Subscribe label, and unscrollable because the page suppresses horizontal overflow. */
.ft-col{min-width:0}

@media(max-width:560px){
  /* The lockup is absolutely centred on wide screens, which takes it out of the flex flow, so on
     a phone the giving button was painted straight over Plan International's own mark: 49px of
     overlap at 320, 24px at 375. Back into the flow, where the browser guarantees separation. */
  .ph-left{flex:0 0 auto}
  .ph-logo{position:static;transform:none;margin:0 auto;min-width:0;flex:0 0 auto}
  .ph-right{margin-left:0}
  /* width:auto and object-fit:contain both matter, and both were missing from the homepage's
     own copy of this rule: the flex row squeezed the box and the mark was stretched to fill it,
     rendering Plan International's registered lockup 25.7% narrower than it is drawn.
     flex:0 0 auto stops the squeeze; object-fit:contain means that if anything ever squeezes it
     again the mark letterboxes rather than distorts. */
  .ph-logo img{height:44px;width:auto;max-width:100%;object-fit:contain}
}

/* ── CHANGE TAGS, pink review tooling, not the design. Matthew, 24 August: "show me whenever
   an update has been made, shows a tag eg new, updated, that way I can see exactly what was
   changed, similar to how we do the comments." Pure CSS, no script: unlike the comments layer
   it must be correct on the very first paint, before any script has a chance to run, or a
   reviewer opening the page mid-review sees nothing wrong and the whole point is lost.
   Section-scoped, the same unit reviewers already scan by and the same unit comments anchor
   to. Colours match the review layer's own palette (--rv:#D6006E, --rv-dk:#A80057) exactly,
   hardcoded rather than borrowed, because this tag must render even on a page where the
   review script never loads. pointer-events:none throughout, so it can never sit between a
   reviewer's right-click and the content underneath it.
   STRIP BEFORE LAUNCH, same as the rest of the review layer: grep 'chg-tag' and 'data-chg'. */
[data-chg]{position:relative}
.chg-tag{position:absolute;top:14px;right:14px;z-index:5;pointer-events:none;
  display:inline-flex;align-items:center;gap:6px;padding:5px 13px 5px 10px;
  border-radius:999px;font-family:'Poppins',Arial,sans-serif;font-weight:700;
  font-size:11px;line-height:1.3;letter-spacing:.09em;text-transform:uppercase;
  background:#D6006E;color:#fff;box-shadow:0 3px 10px rgba(214,0,110,.32)}
.chg-tag::before{content:"";width:6px;height:6px;border-radius:50%;background:#fff;flex:none}
.chg-tag.chg-updated{background:#A80057}
@media(max-width:640px){
  .chg-tag{top:8px;right:8px;font-size:10px;padding:4px 11px 4px 8px}
}
@media print{ .chg-tag{display:none} }


/* ── GIVING DRAWER vs THE COOKIE CARD ────────────────────────────────────────────────────────
   The cookie card is fixed bottom-right at z-index 900. The giving drawer opens over the same
   corner and sat at z-index 2, so a first-time visitor who pressed Start giving before
   dismissing cookies got the lower half of the form covered: the CHF 500 option, Other, and
   the Give button itself. Every first visit, which at launch is every visit that matters.

   Written as .panel.open (0,2,0) rather than .panel (0,1,0) so it wins wherever the base rule
   sits, and placed INSIDE SHARED-WITH-HOME so it actually reaches the homepage. The first
   attempt went in at the top of this file, outside the region, and never arrived. */
.panel.open{z-index:950}
body:has(.panel.open) .ck{opacity:0;pointer-events:none}

/* Tertiary hero link: the yellow button became the giving ask on 3 Sep 2026, so the case link
   sits beside it rather than competing with it. */
.cta-see{align-self:center;margin-left:2px}


/* ── GIVING PLATFORMS BAND ───────────────────────────────────────────────────────────────────
   .dd is a twelve column grid and every card type declares its own span (.dd-plan is span 5).
   The platforms cards were added on 3 Sep without one, so each took a single column: three
   cards in three tracks with nine empty tracks trailing, the money band rendering in the left
   half of the screen with 822px of dead space beside it and the endowment heading wrapping onto
   four lines. Measured by the studio panel at 1280px, 1440px and 2040px.
   Equal spans, because these are three peer platforms and Maureen's order already carries the
   hierarchy. Below 1000px the existing .dd-card span 12 rule takes over and they stack. */
#platforms .dd-card{grid-column:span 4}
/* And the matching stack, at the SAME specificity, or the desktop fix silently breaks the phone.
   "#platforms .dd-card" is (1,1,0). The mobile rule that stacks every other card, ".dd-card
   {grid-column:span 12}" inside @media(max-width:700px), is (0,1,0). An id beats a class no
   matter which media query it sits in, so the fix that made this band fill the desktop also
   pinned it to three columns on a 375px phone: the Foundation's core giving argument rendered as
   three slivers on every phone for two days. Found by the mobile specialist, and it is exactly
   the trap of reaching for an id to win a cascade fight. */
@media(max-width:700px){ #platforms .dd-card{grid-column:span 12} }


/* ── CONSENT CARD AND GIVING DRAWER, TOUCH AND OVERLAP ───────────────────────────────────────
   From the studio panel. Two of its three claims here held up when I measured them live and one
   did not, so only the real ones are fixed.
   NOT FIXED, because it is not true: the panel reported the two consent buttons as 27px tall.
   They compute to 52px and there is no mobile override; measured live at 51x238. Left alone.
   FIXED: the "Choose what to allow" control measured 33px, under the 44px minimum for a touch
   target, and it is the control that leads to the granular consent a regulator expects to be
   reachable. And the drawer's sticky Give button could pass over the sentence saying what the
   money funds, so the button now carries its own opaque band and the drawer keeps clearance
   below its last element. */
.ck-choose{min-height:44px;padding:11px 0}

/* The sticky Give button was sitting ON TOP of the sentence that says what the money funds.
   My first attempt at this made it worse: a soft box-shadow meant to separate the button from
   the content behind it instead faded the sentence out, so the line read as a rendering fault
   halfway through the words. Seen in a screenshot, not in a measurement, which is the only way
   this kind of thing shows up.
   The sentence gets clearance of its own so it is never trapped under the button at rest, and
   the button keeps a hard opaque edge rather than a gradient, so anything scrolling past it is
   cleanly cut rather than smeared. */
/* The button and the line under it are ONE pinned bar now. Before this the "see all the ways to
   give" line sat at y=809 in a panel whose visible area ended around y=750, so it rendered below
   the fold with no scroll affordance: elementFromPoint at its centre returned nothing and the
   link was unreachable. It is the route to legacies, shares and bank transfer, which is where
   the large gifts actually come from, and it was invisible. Pinning both together means neither
   can fall off the bottom whatever the panel height. */
/* THE DRAWER IS A COLUMN, NOT A SCROLLING BOX WITH A STICKY LID.
   The content is genuinely 290px taller than the panel at a 795px viewport, so it has to scroll.
   With the button sticky INSIDE the scroller it pinned itself to the bottom of the visible area
   and sat on top of whatever was at that position, which was the sentence saying what the money
   funds. I patched that twice, once with a margin and once with an opaque band, and both times
   it came back somewhere else, because the architecture was wrong rather than the numbers.
   Now: the panel is a flex column, the fields scroll in their own region, and the button and the
   ways-to-give line are a fixed foot outside that region. Nothing can be covered, at any height,
   because nothing overlaps anything. */
/* The custom dropdown site.js builds around every <select class="gp-select">. The select itself
   stays in the DOM (site.js hides it only once .js confirms the replacement exists) so a
   no-JavaScript visitor still gets a normal, working, native field; this is what a JavaScript
   visitor sees instead, in the site's own type and colour rather than the OS's. Lives inside
   SHARED-WITH-HOME: the give panel this belongs to is on every page, homepage included. */
.gp-dd{position:relative}
.js .gp-dd select.gp-select{position:absolute;opacity:0;pointer-events:none;height:1px;width:1px;overflow:hidden}
.gp-dd-btn{width:100%;height:52px;border-radius:var(--r-sm);border:1.5px solid var(--grey);background:#fff;
  padding:0 44px 0 16px;font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:14.5px;
  color:var(--ink);cursor:pointer;text-align:left;display:flex;align-items:center;position:relative}
/* flex:1 + min-width:0, not the max-width:100% this had: a flex child's default min-width is
   auto, which is its OWN content's width, so on a narrow phone this refused to shrink below
   "Annual giving · Education Uninterrupted" at all, pushed .gp-dd-btn wider than the panel, and
   made the WHOLE giving drawer scroll sideways, clipping the GBP currency button and the Other
   amount button off-screen with no visible scrollbar to say so. Found live 6 Sep 2026 at 375px;
   confirmed absent at desktop width, where there was room to spare either way. min-width:0 is
   what actually lets text-overflow:ellipsis engage under real pressure. */
.gp-dd-btn .gp-dd-val{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}
.gp-dd-btn svg{position:absolute;right:15px;top:50%;width:20px;height:20px;stroke:var(--plan-blue);
  pointer-events:none;transform:translateY(-50%);transition:transform .16s var(--sw)}
.gp-dd-btn[aria-expanded="true"] svg{transform:translateY(-50%) rotate(180deg)}
.gp-dd-btn:focus-visible{outline:3px solid var(--yellow);outline-offset:2px}
.gp-dd-list{position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:20;background:#fff;
  border:1.5px solid var(--keyline);border-radius:var(--r-sm);box-shadow:0 12px 28px rgba(16,17,20,.16);
  list-style:none;margin:0;padding:6px;max-height:240px;overflow-y:auto}
.gp-dd-opt{font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:13.5px;color:var(--ink);
  padding:11px 12px;border-radius:var(--r-sm);cursor:pointer;line-height:1.35}
.gp-dd-opt:hover,.gp-dd-opt.is-active{background:#cfe4f6}
.gp-dd-opt[aria-selected="true"]{background:var(--plan-blue);color:#fff}
.panel-give{display:flex;flex-direction:column;overflow:hidden}
.panel-give #gv-form{display:flex;flex-direction:column;min-height:0;flex:1}
/* flex:1 here (until 6 Sep 2026) meant the fields always stretched to fill whatever the panel
   had left over, so once the height cuts above made the fields genuinely shorter than a tall
   screen's drawer, the leftover space showed up as a dead gap INSIDE the scroll area, above the
   foot, rather than not existing. flex:0 1 auto: the fields take exactly the room their own
   content needs, shrinking (min-height:0 still lets that happen) and scrolling only when a
   short viewport genuinely has less room than that. Any true leftover space now falls where it
   belongs, as plain background below the foot, not as a gap inside the content. */
/* Two findings, one cause, live 6 Sep 2026: the OS's own overlay scrollbar on this element is
   invisible until touched, so when Other amount pushed the email field past the fold, or the
   Stripe Payment Element's own Link "save my info" fields pushed past it on the pay step,
   nothing on screen said there was more below. A real, always-visible thin scrollbar whenever
   this genuinely overflows is the fix — not hiding it, making it seen. */
/* Matthew: "under the far left of this field, you can see where the yellow part is getting cut
   off." The focus ring on the fields is `outline:3px` at `outline-offset:2px`, so it is drawn
   5px OUTSIDE the input on every side. This container scrolls, and a box that scrolls on one
   axis clips on the other too: `overflow-y:auto` computes `overflow-x` from visible to auto,
   which clips. With the inputs sitting flush against the container's left content edge, the
   left 5px of every focus ring was being cut off, which is what he could see.
   The fix gives the ring somewhere to be drawn: 6px of horizontal padding, pulled straight back
   out with a matching negative margin, so the ring has room while the form's own alignment,
   width and scrollbar position are all exactly where they were. */
.gp-scroll{flex:0 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding-left:6px;margin-left:-6px;
  padding-right:10px;margin-right:-6px;scrollbar-width:thin;scrollbar-color:var(--grey) transparent}
.gp-scroll::-webkit-scrollbar{width:6px}
.gp-scroll::-webkit-scrollbar-track{background:transparent}
.gp-scroll::-webkit-scrollbar-thumb{background:var(--grey);border-radius:999px}
/* On a short viewport, a landscape phone above all, the part of the form that does NOT scroll
   (the button, the two notes and the trust list) is taller than the panel, so the scrolling part
   was handed nothing: measured at 812x375, .gp-scroll was 0px tall holding 487px of content, and
   the donor could not reach the amount or the designation at all. Below 560px of height the whole
   form scrolls as one column instead. Found by a critique panel, reproduced by measurement. */
@media(max-height:560px){
  .panel-give #gv-form{display:block;overflow-y:auto;overscroll-behavior:contain;min-height:0}
  .panel-give .gp-scroll{overflow:visible;flex:none}
}
.gp-impact{margin-bottom:4px}
.gp-foot{flex:none;background:var(--paper);padding:10px 0 12px;margin-top:4px}
.gp-foot .gp-note{margin:10px 0 0!important}
.gp-foot .gp-trust{margin-top:10px}
.gp-foot::before{content:"";display:block;height:1px;background:var(--line);
  margin:0 0 14px}
/* NOT a colour change: this button was always the site's yellow pill (background:var(--yellow),
   line 656), dark ink text for contrast. This rule used to also carry
   "background:var(--plan-blue)", silently repainting every .gp-cta on the page blue with the
   wrong (dark-on-blue) text colour on top of it, found live 6 Sep 2026. position:static is the
   only thing this rule was ever meant to do: the button moved out of the sticky-inside-scroller
   layout into .gp-foot, which is fixed outside the scroll region, so sticky positioning no
   longer applies. */
.gp-cta{position:static}
/* Above the button, and lifted into its own stacking layer. Under the button it was
   unreachable: a real click on it did not navigate, twice. The route to legacies, shares
   and bank transfer is where large gifts actually come from, so it does not go anywhere
   it can be swallowed by a 60px sticky control. */
.gp-foot-note{margin:0 0 12px;font-size:13.5px;text-align:center;
  position:relative;z-index:5}
.gp-foot-note a{position:relative;z-index:5}

/* A 44px way out. The drawer declared aria-modal and had no close control at all, and on a phone
   it covers the entire screen below the header. */
.gp-close{position:absolute;top:14px;right:26px;width:44px;height:44px;display:grid;
  place-items:center;background:none;border:0;color:var(--ink);cursor:pointer;
  border-radius:50%;z-index:2}
.gp-close svg{width:22px;height:22px}
.gp-close:hover{background:var(--paper-2)}
.gp-close:focus-visible{outline:3px solid var(--yellow);outline-offset:2px}
.panel-give{position:fixed}

/* ── PANEL MOTION AND REDUCED MOTION ─────────────────────────────────────────────────────────
   From the motion specialist, who measured this frame by frame in a browser rather than reading
   the file. Both fixes live HERE, inside SHARED-WITH-HOME, because .panel is declared outside it
   and the homepage keeps its own copy of everything outside: a fix written at the original rule
   would reach nine pages and silently miss the one the client opens first. That has happened
   before on this project and it is what this region exists to prevent.

   1. THE DRAWER CROSS-FADED WHEN IT SHOULD SLIDE.
   The giving panel is 440px wide, fixed to the right edge, and it arrived by fading in over an
   18px nudge. 18px on a 440px object is four per cent of its own width, so it read as a layer
   the browser drew rather than a drawer the reader pulled. Below 560px it becomes a full-screen
   sheet still arriving on the same 18px, giving no sense of where it came from or how to send it
   back. It now slides from its own edge, and closes faster than it opens, which is the normal
   asymmetry for a surface being dismissed. Opacity stays near 1 through the slide: an object
   arriving from off-screen should not also be fading, or the reader gets two gestures for one
   event. The easing is the site's own --sw curve, which has no control point above 1 and so
   cannot overshoot. This is the interaction a major donor actually performs.

   2. REDUCED MOTION LOST THE CASCADE, MEASURED NOT ASSUMED.
   The reduce block sets .panel{transition:none}, specificity (0,1,0). .panel.open declares its
   own 500ms transition at (0,2,0) and wins outright, so a reader who has asked their operating
   system for less motion got a 500ms animated open and an instant close: the one asymmetry worse
   than animating both ends. Restated here with !important, which is what the rest of this file
   already does for the same reason. Six further controls declared durations that no reduce block
   reached, all confirmed present in the DOM: the consent chevron and switches, the amount buttons
   inside the drawer, and three button hovers. */

.panel{transform:translateX(100%);opacity:1;
  transition:transform 420ms var(--sw),opacity 160ms linear,visibility 0s linear 420ms}
.panel-nav{transform:translateX(-100%)}
.panel.open{transform:none;opacity:1;
  transition:transform 420ms var(--sw),opacity 120ms linear,visibility 0s}
.panel:not(.open){transition-duration:300ms,120ms,0s;
  transition-timing-function:cubic-bezier(.4,0,1,1),linear,linear}

@media (prefers-reduced-motion:reduce){
  .panel,.panel.open,.panel:not(.open),.panel-nav,.panel-nav.open,
  .hdr-scrim,.hdr-scrim.on{transition:none!important}
  .ck-chev,.ck-track,.ck-track::after,.ck-btn,.nl-btn,.btn-donate,
  .gp-opt span{transition:none!important}
  .ck-btn:hover,.nl-btn:hover,.btn-donate:hover{transform:none!important}
}


/* ══ LAYOUT VOCABULARY ═══════════════════════════════════════════════════════════════════════
   Matthew, 4 Sep 2026: "You're reusing too many elements. It's the same sections over and over
   again... This looks like it was just done, like I bought this template online."

   He is right and the count proves it. Forty-six sections across eleven pages and every one of
   them is the same object: eyebrow, headline, intro paragraph, then a slot holding one of five
   fillings. There was exactly ONE image treatment in the entire site, img_band(), which does
   full-width-photo-with-caption and nothing else, used four times. No function existed that
   could put a picture beside a paragraph. On a site about girls.

   These are the missing shapes. Every one is a real editorial device rather than another
   rectangle: the picture changes side, breaks the column, goes round, carries the text, or sits
   inside the reading line. All of them stack to a single column on a phone, all of them respect
   the reveal system, and none of them introduces a colour or a typeface the brand does not
   already have. In WordPress each becomes one block with a layout choice in the sidebar, which
   is what lets Daniela build a page that does not look like the last one.
   ─────────────────────────────────────────────────────────────────────────────────────────── */

/* 1 ── SPLIT: picture one side, words the other. The side is a choice, not a default. */
/* Spec 1.6 said "pairs top-aligned," on the assumption the two sides would run roughly the
   same length. Found live 6 Sep 2026, three separate pages: when the words are much shorter
   than the photo (two bullet points beside a full portrait), top-aligning both just left the
   photo running on past a text column that stopped 140-280px short, a bare white gap where
   nothing else was placed — Programmes/Girls in Crisis, Philanthropy Council/Convening, Why
   Girls/The Difference and The Case, all the same component, all the same shape of gap.
   align-items:stretch makes both columns the row's full height (no shorter column, no gap);
   ls-body centres its own content inside that height, so a short pair reads as deliberately
   centred beside the photo instead of stranded at the top of empty space, and a pair whose
   words already run the photo's length looks exactly as it did before, no height to spare. */
.lay-split{display:grid;grid-template-columns:repeat(12,1fr);gap:clamp(24px,4vw,64px);
  align-items:stretch}
.lay-split .ls-media{grid-column:span 6;position:relative;min-width:0}
.lay-split .ls-body{grid-column:span 6;min-width:0;display:flex;flex-direction:column;justify-content:center}
.lay-split.is-right .ls-media{order:2}
.lay-split.is-right .ls-body{order:1}
/* Optional per-instance resize, added 12 September 2026 (Section block's "Picture size" field,
   drag the picture's own edge on the canvas to set it): only takes effect when a real, non-default
   value is actually written inline as --ggf-img-w, so every split section already on the site
   keeps the exact repeat(12,1fr)/span-6 grid above, byte-for-byte untouched, unless someone has
   deliberately resized this one. grid-column overrides make the order:2/order:1 pair above inert
   for a resized instance (harmless: explicit placement always wins over order), so is-right still
   flips the correct side. */
@media(min-width:861px){
  .lay-split[style*="--ggf-img-w"]{grid-template-columns:var(--ggf-img-w) minmax(0,1fr)}
  .lay-split[style*="--ggf-img-w"] .ls-media{grid-column:1}
  .lay-split[style*="--ggf-img-w"] .ls-body{grid-column:2}
  .lay-split[style*="--ggf-img-w"].is-right{grid-template-columns:minmax(0,1fr) var(--ggf-img-w)}
  .lay-split[style*="--ggf-img-w"].is-right .ls-media{grid-column:2}
  .lay-split[style*="--ggf-img-w"].is-right .ls-body{grid-column:1}
}
/* 16px, because that is what every other photograph on this site already computes to. I set
   these square after the design gate rejected a 2px radius, and squaring them was the wrong
   correction: it left one rounded photograph and one sharp one in the same section, which is
   what Matthew saw. The gate permits 0, the pill, 8-16px, the panel or a circle. The house
   value is 16px. Match the house.
   And crop rather than stretch: the split image was rendering 1431x954 with object-fit:fill,
   which is a distorted picture of a girl, not a cropped one. */
/* Spec 1.8: one default for both picture devices, then a stamped ratio per call. split() and
   overlap() stamp is-r43 / is-r32 / is-r45 / is-r11 / is-r1610 / is-rauto on their outer div. */
.lay-split .ls-media img,.lay-overlap .lo-media img{width:100%;height:auto;display:block;border-radius:var(--r);
  aspect-ratio:4/3;object-fit:cover}
.is-r32 .ls-media img,.is-r32 .lo-media img{aspect-ratio:3/2}
.is-r45 .ls-media img,.is-r45 .lo-media img{aspect-ratio:4/5}
.is-r11 .ls-media img,.is-r11 .lo-media img{aspect-ratio:1/1}
.is-r1610 .ls-media img,.is-r1610 .lo-media img{aspect-ratio:16/10}
.is-rauto .ls-media img,.is-rauto .lo-media img{aspect-ratio:auto;object-fit:contain;border-radius:0}
/* the narrow variant gives the words the room and keeps the picture as an accent */
.lay-split.is-narrow .ls-media{grid-column:span 5}
.lay-split.is-narrow .ls-body{grid-column:span 7}
/* BLEED: the picture runs off the edge of the page. The single cheapest way to stop a layout
   reading as a box, because the box no longer has a fourth side. */
/* Spec 1.4. The bleed is the distance from the wrap's edge to the viewport's, so the picture
   runs exactly to the screen edge and never past it on the inner side. Accepted in writing:
   scrollbar-gutter:stable makes 100vw include the scrollbar, so this overshoots by about 8px on
   the outer side, as the old calc did; body{overflow-x:clip} hides it. The two inner corners keep
   the house radius so the object still reads as the same family as every other photograph. */
.lay-split.is-bleed{--bleed:calc(max(4vw,(100vw - 1680px)/2) + var(--gutter))}
.lay-split.is-bleed .ls-media{margin-inline-start:calc(-1 * var(--bleed))}
.lay-split.is-bleed.is-right .ls-media{margin-inline-start:0;margin-inline-end:calc(-1 * var(--bleed))}
.lay-split.is-bleed .ls-media img{border-radius:0 var(--r) var(--r) 0}
.lay-split.is-bleed.is-right .ls-media img{border-radius:var(--r) 0 0 var(--r)}

/* ROUND, the component: removed 8 September 2026. Matthew, on the "Girls in Leadership/Crisis/
   Innovation" row it drew: "Remove this section altogether." Its only caller was the hand-placed
   block in v9/index.html's #mission section, now gone; round_row(), the build.py generator for
   this same component, was already dead (zero call sites, confirmed separately). Nothing else on
   the site used .lay-round, so all of it goes together: the flex row, the circular-photo crop,
   the doodle-behind-the-photo blobs added earlier the same day, the spin keyframe. */

/* 3 ── OVERLAP: a card sits ON the picture and breaks its edge. Two planes instead of one. */
.lay-overlap{position:relative;display:grid;grid-template-columns:repeat(12,1fr)}
.lay-overlap .lo-media{grid-column:1 / span 9;grid-row:1;position:relative}
/* grid-row:1 on BOTH children or they auto-place into separate rows and the card lands
   above the picture instead of on it, which is a stack, not an overlap. */
/* align-self:end, not center. A 167px card centred on a 792px photograph leaves 300px of
   nothing above it and 300px below, which is the 'doesn't look properly designed' Matthew
   saw. Sitting it low, overlapping the bottom corner, is what the device is for: the card
   holds the base of the picture down instead of floating in a void. */
.lay-overlap .lo-card{grid-column:8 / span 5;grid-row:1;align-self:end;margin-bottom:-30px;
  background:var(--paper);padding:clamp(24px,3vw,40px);
  border-radius:var(--r);box-shadow:var(--shadow-2);position:relative;z-index:1}
.lay-overlap.is-right .lo-media{grid-column:4 / span 9;grid-row:1}
.lay-overlap.is-right .lo-card{grid-column:1 / span 5}
.lay-overlap .lo-card h3{margin:0 0 12px}
.lay-overlap .lo-card p:last-child{margin-bottom:0}
/* on blue, the card inverts rather than sitting as a white slab on a blue field */

/* 4 ── TESTIMONY: a round portrait and a quotation set large. The one device this site had no
   version of at all, on a site whose whole argument rests on people. */
.lay-say{display:grid;grid-template-columns:repeat(12,1fr);column-gap:clamp(22px,3.5vw,52px);row-gap:0;
  grid-template-rows:auto 1fr;align-items:start}
/* Spec 1.5. The portrait spans both rows; the quotation is row 1, the narrative row 2. Row 2 is
   1fr so a portrait taller than the quotation stretches the narrative's row, never the gap. */
.lay-say .lsay-shot{grid-column:1 / span 3;grid-row:1 / span 2;align-self:start;aspect-ratio:1;border-radius:50%;overflow:hidden}
.lay-say .lsay-shot img{width:100%;height:100%;object-fit:cover;display:block}
.lay-say .lsay-body{grid-column:4 / span 9;grid-row:1;min-width:0;padding-top:var(--s2)}
.lay-say blockquote{margin:0;font-family:var(--disp,inherit);font-weight:700;
  font-size:clamp(22px,2.9vw,38px);line-height:1.22;letter-spacing:-.015em}
.lay-say .lsay-who{margin-top:var(--s2);font-size:15px;color:var(--grey)}
.lay-say .lsay-who b{color:var(--ink);font-weight:700}

/* 5 ── DUO: two pictures at different sizes, one dropped below the other. Asymmetry, which is
   what a hand-made page has and a template does not. */
.lay-duo{display:grid;grid-template-columns:repeat(12,1fr);gap:clamp(18px,2.5vw,34px);
  align-items:start}
.lay-duo figure{margin:0;min-width:0}
.lay-duo .ld-a{grid-column:span 7}
.lay-duo .ld-b{grid-column:span 5;margin-top:clamp(30px,7vw,90px)}
.lay-duo img{width:100%;height:auto;display:block;border-radius:var(--r)}
.lay-duo figcaption{margin-top:10px;font-size:14px;color:var(--grey)}

/* 8 ── REGISTER (spec 5.1). The name is the portrait: no initials, avatars, silhouettes, dashed
   frames or boxes. One 4px rule above the list, a hairline between rows, the first grid row's
   hairline transparent so the rule is not doubled. Portraits switch on per group only when every
   member has one; register() in build.py refuses a mixed group. The ledger is the same object
   holding three short columns of facts (home #platforms, give #designations, endowment #what). */
.lay-register{list-style:none;margin:var(--s1) 0 0;padding:var(--s1) 0 0;display:grid;grid-template-columns:repeat(var(--reg-cols,2),minmax(0,1fr));
  column-gap:clamp(40px,5vw,96px);border-top:var(--rule)}
.lay-register.is-1{--reg-cols:1} .lay-register.is-3{--reg-cols:3} .lay-register.is-first{margin-top:0}
.reg-row{padding:var(--s3) 0;border-top:1px solid var(--hairline);min-width:0}
.is-2>.reg-row:nth-child(-n+2),.is-3>.reg-row:nth-child(-n+3),.is-1>.reg-row:first-child{border-top-color:transparent}
.reg-row h3{margin:0 0 var(--s1);font-size:26px;line-height:1.15;letter-spacing:-.01em;color:var(--ink)}
.reg-row p{margin:0;font-size:15.5px;line-height:1.6;color:var(--ink);max-width:34em}
.reg-row .dd-link{padding-top:var(--s2)}
/* After .reg-row p on purpose: at (0,2,0) it beats that rule's (0,1,1), which was painting the role 15.5px ink. */
.reg-row .reg-role,.lsay-rail .reg-role{margin:0 0 var(--s1);font:700 13px/1 'Poppins',Arial,sans-serif;letter-spacing:.1em;text-transform:uppercase;color:var(--plan-blue-dk,#005AA6);max-width:none}
.reg-lead+.lay-register{margin-top:var(--s3)}
.reg-row.is-anon h3{color:var(--grey);font-size:20px}
.is-ledger .reg-row{border-top:0}
.is-ledger .reg-row+.reg-row{border-left:1px solid var(--hairline);padding-left:clamp(32px,4vw,64px)}
.is-ledger .reg-row p{max-width:30em}
.is-portraits .reg-row{display:grid;grid-template-columns:96px minmax(0,1fr);column-gap:var(--s3);align-items:start}
.is-portraits .reg-shot{grid-row:1/span 4;width:96px;aspect-ratio:1;border-radius:50%;overflow:hidden}
.is-portraits .reg-shot img{width:100%;height:100%;object-fit:cover;display:block}
.is-portraits .reg-row>:not(.reg-shot){grid-column:2}
/* The line that introduces a register, and the statement that stands in for one (5.3). */
.reg-lead{margin:var(--s4) 0 0;font-size:15.5px;line-height:1.6;color:var(--ink);max-width:var(--measure)}
.statement{margin:var(--s4) 0 0;font:18px/1.6 Arial,Helvetica,sans-serif;color:var(--ink);max-width:28em}
/* The typographic testimony (5.2): a rail of role, name and line beside the quotation, for a
   voice on the record with no photograph yet. When one arrives, drop is_type. */
.lay-say.is-type .lsay-rail{grid-column:1/span 3;grid-row:1/span 2;align-self:start;border-left:var(--rule);padding-left:clamp(16px,1.6vw,26px);min-width:0}
.lay-say.is-type .lsay-rail h3{margin:0 0 var(--s1);font-size:26px;line-height:1.15;letter-spacing:-.01em;color:var(--ink)}
.lay-say.is-type .lsay-line{margin:0;font-size:13.5px;line-height:1.5;color:var(--grey)}
.lay-say.is-type .lsay-body{padding-top:0}
.lay-say .src{margin:var(--s2) 0 0;font-size:13.5px;line-height:1.5;color:var(--grey)}
@media(max-width:860px){
  .lay-register,.lay-register.is-1,.lay-register.is-2,.lay-register.is-3{--reg-cols:1}  /* must outrank .is-3 */
  .is-2>.reg-row:nth-child(-n+2),.is-3>.reg-row:nth-child(-n+3){border-top-color:var(--hairline)}
  .lay-register>.reg-row:first-child{border-top-color:transparent}
  .is-portraits .reg-row{grid-template-columns:72px minmax(0,1fr);column-gap:14px} .is-portraits .reg-shot{width:72px}
  /* The ledger stacks with the rest: each later row loses its left border for a hairline above. */
  .is-ledger .reg-row+.reg-row{border-left:0;border-top:1px solid var(--hairline);padding:28px 0 0;margin-top:28px}
  .lay-say.is-type .lsay-rail{grid-column:span 12;grid-row:auto;margin-bottom:28px}
}

/* 6 ── WORDS ON THE PICTURE, rather than beside it. */
.lay-on{position:relative;min-height:clamp(340px,46vw,560px);display:grid;
  align-items:end;overflow:hidden;border-radius:var(--r)}
.lay-on img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.lay-on .lon-scrim{position:absolute;inset:0;
  background:linear-gradient(to top,rgba(10,42,67,.86) 0%,rgba(10,42,67,.45) 46%,rgba(10,42,67,0) 78%)}
.lay-on .lon-body{position:relative;padding:clamp(26px,4vw,58px);color:#fff;max-width:62ch}
.lay-on .lon-body h2{color:#fff;margin:0 0 12px}
.lay-on .lon-body p{color:rgba(255,255,255,.9);margin:0}

/* 7 ── FIGURE IN THE READING LINE: a small picture inside the text column, floated, the way a
   printed page does it. Nothing on this site could do this. */
.lay-fig{float:right;width:min(46%,340px);margin:6px 0 22px 30px}
.lay-fig.is-left{float:left;margin:6px 30px 22px 0}
.lay-fig img{width:100%;height:auto;display:block;border-radius:var(--r)}
.lay-fig.is-round img{border-radius:50%;aspect-ratio:1;object-fit:cover}
.lay-fig figcaption{margin-top:9px;font-size:13.5px;line-height:1.5;color:var(--grey)}

/* ── STACKING. Every one of these becomes a single column, and the float becomes a block. ── */
@media(max-width:860px){
  .lay-split .ls-media,.lay-split .ls-body,
  .lay-split.is-narrow .ls-media,.lay-split.is-narrow .ls-body{grid-column:span 12}
  .lay-split.is-right .ls-media{order:0}
  .lay-split.is-right .ls-body{order:1}
  .lay-split.is-bleed .ls-media{margin-inline:0}
  .lay-split.is-bleed .ls-media img,.lay-split.is-bleed.is-right .ls-media img{border-radius:var(--r)}
  .lay-overlap .lo-media,.lay-overlap.is-right .lo-media{grid-column:1 / span 12}
  .lay-overlap .lo-card,.lay-overlap.is-right .lo-card{grid-column:1 / span 12;grid-row:auto;
    margin:-30px 20px 0;padding:28px}  /* spec 3.3: pulled up 30 with a 20 inset */
  .lay-say{grid-template-rows:none}
  .lay-say .lsay-shot{grid-column:span 12;grid-row:auto;max-width:150px}
  .lay-say .lsay-body{grid-column:span 12;grid-row:auto}
  .lay-duo .ld-a,.lay-duo .ld-b{grid-column:span 12}
  .lay-duo .ld-b{margin-top:0}
  .lay-fig,.lay-fig.is-left{float:none;width:100%;margin:0 0 20px}
}


/* The narrative that follows a testimony should hang off the same left edge as the quotation,
   not float in the middle of the page. The portrait occupies three of twelve columns, so the
   prose starts where the quote starts and the two read as one object rather than two. */
/* Aligned by sharing the grid, not by approximating it with a calc. The first attempt used
   calc(25% + gap*0.75) and landed 26px out, because the gap is a clamp and the column is not
   exactly a quarter. Same twelve tracks, same gap, content placed in columns 4 to 12: the prose
   now starts precisely where the quotation starts, at every width, with no arithmetic. */
.lay-say .say-after{grid-column:4 / span 9;grid-row:2;min-width:0;margin-top:var(--s3)} /* spec 1.5: 'Amara, 16' to the narrative is 28 */
/* ONE grid child holding everything, not one per paragraph. Making each paragraph a grid item
   aligned them correctly and then broke the float: a floated figure and the text it should wrap
   into were siblings in a grid, so the picture took a row of its own and sat there alone. The
   column is the grid item; the float lives inside it, where floats work. */
.lay-say .say-after .say-col{max-width:var(--measure)}
.lay-say .say-after .say-col::after{content:"";display:block;clear:both}
.lay-say .say-after .lay-fig{width:min(38%,240px);margin:4px 0 18px 26px}
@media(max-width:860px){
  .lay-say .say-after{grid-column:1 / span 12;grid-row:auto}
}


/* Matthew, 5 Sep: "That text you have in very small italics: there is no reason for it." The
   note, figtag and story-credit classes rendered in italic Georgia. Now the body face, upright,
   one step smaller than body copy, and nothing else. Paragraphs in a story get air between them;
   Amara's narrative was running together as one block. */
.note,.figtag,.story-credit,.band-note{font-family:inherit;font-style:normal;font-size:14px;color:var(--grey)}
.say-col p+p{margin-top:14px}
.say-col .story-credit{margin-top:22px}
/* ══ THE MAST (spec 2, 5 Sep 2026). Header, sheets, menu, drawer and offsets. Everything here is
   inside SHARED-WITH-HOME because the header markup is synced into the homepage. The estate
   header's rules above stay behind GGF_HEADER=estate and are inert when header.plan is absent.
   Z ladder inside the header's own stacking context: menu 78, bar 80, scrim 85, drawer 90, skip 100. */
.skip{position:absolute;top:20px;left:24px;z-index:100;display:inline-flex;align-items:center;height:40px;padding:0 18px;border-radius:999px;
  background:var(--yellow);color:var(--ink);font:700 15px/1 'Poppins',Arial,sans-serif;text-decoration:none;
  transform:translateY(-200%);opacity:0;pointer-events:none}
/* :focus, not :focus-visible: nothing but a keyboard can reach an off-screen link, and Chrome does not
   count a scripted focus() as keyboard focus, which is how the gate caught it staying hidden. */
.skip:focus{transform:none;opacity:1;pointer-events:auto;outline:3px solid #fff;outline-offset:3px}

header.mast{position:fixed;top:var(--inset);left:var(--inset);right:var(--inset);z-index:80;background:var(--plan-blue);
  border-radius:var(--r);height:80px;box-shadow:none;transition:height 240ms var(--sw)}
header.mast.is-condensed{height:88px}
.mast-in{position:relative;z-index:80;display:flex;align-items:center;height:100%;padding-inline:clamp(20px,calc(4vw - 14px),52px)}
.mast .hdr-scrim{z-index:85}
.mast .panel{top:0;z-index:90}
@media(max-width:559px){ .mast .panel{width:100vw} }

/* The lockup: Plan's flag (its full mobile logo, white ground, blue figure and wordmark, 44px
   tall is about 115 wide), a hairline divider, and the Foundation's name as live text in the
   lockup's own treatment. The PNG lockup is the one-class fallback under .mast.is-artwork. */
.mast-lockup{display:flex;align-items:center;color:#fff;text-decoration:none;flex:none;border-radius:var(--r-sm)}
.mast-flag{height:44px;width:auto;display:block;flex:none;transition:height 240ms var(--sw)}
/* Matthew, 6 September 2026: "once you start scrolling it gets too narrow. Instead of making
   it smaller, make it a bit larger." So the scrolled bar is 4px TALLER than at rest and nothing
   inside it shrinks: flag, wordmark, navigation and the donate button keep their resting size.
   The class stays because the shadow and the sheet geometry hang off it. */
.mast.is-condensed .mast-flag{height:44px}
.mast-art{display:none;height:64px;width:auto;object-fit:contain}
.mast.is-artwork .mast-flag,.mast.is-artwork .mast-div,.mast.is-artwork .mast-word{display:none}
.mast.is-artwork .mast-art{display:block;object-fit:contain}
.mast-div{width:1px;height:36px;background:rgba(255,255,255,.4);margin:0 14px;flex:none;transition:height 240ms var(--sw)}
.mast.is-condensed .mast-div{height:36px}
.mast-word{font:700 13px/1.15 'Poppins',Arial,sans-serif;letter-spacing:.1em;text-transform:uppercase;color:#fff;white-space:nowrap;transition:font-size 240ms var(--sw)}
.mast.is-condensed .mast-word{font-size:13px}
.mast-lockup:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}

/* The five links. Only the current section's label carries the yellow stroke, held static:
   without this rule the m-ready gate below holds it at scaleX(0) for ever, the header not being
   inside a .reveal. Hover on the others is a straight 2px white line at 60%, no horizontal motion. */
.mast-nav{margin-left:auto}
/* THE DROPDOWN BUG, found properly 7 September 2026. These two rules were written for the one
   horizontal row of top-level nav items, but `.mast-nav ul` matches EVERY ul inside the nav,
   and the dropdown sheets are uls inside the nav. `.mast-nav ul` (one class + one element)
   also outranks `.mast-sheet` (one class), so the sheet was being laid out as a horizontal
   flex row with a 32px gap: a 260px wide, 38px tall strip with its two links squashed side by
   side, which is exactly what Matthew kept seeing. Adding `display:block` to `.mast-sheet` on
   6 September did nothing for the same reason it looked like it should have worked: it lost
   the specificity fight silently, with no error anywhere to notice. The fix is the child
   combinator, so these only ever style the top-level row they were written for. */
.mast-nav > ul{display:flex;align-items:center;gap:32px;margin:0;padding:0;list-style:none}
.mast-nav > ul > li{display:flex;align-items:center;gap:2px}
.mast-nav a{display:inline-block;position:relative;padding:10px 0;color:#fff;text-decoration:none;white-space:nowrap;
  font:600 15px/1.2 'Poppins',Arial,sans-serif;transition:font-size 240ms var(--sw)}
.mast.is-condensed .mast-nav a{font-size:15px}
.mast-nav a::after{content:"";position:absolute;left:0;right:0;bottom:4px;height:2px;background:rgba(255,255,255,.6);opacity:0;transition:opacity 160ms var(--sw)}
.mast-nav a:hover::after,.mast-nav a:focus-visible::after{opacity:1}
/* Was "display:none": the current page's own mark was the doodle underline wrapping its label
   (build.py's mast_nav()), so this line hid the plain hover-bar underneath rather than have two
   marks stack. Now that .doodle is a retired, empty rule (brand.css, 8 September 2026), that
   mark is gone, and the current page in the nav had nothing at all, not even on hover. This
   reuses the same plain bar every other link already shows on hover, just permanently on for
   the one that's current, rather than reach for another doodle to replace the one just removed. */
.mast-nav a.is-current::after{opacity:1}
.mast-nav a:focus-visible,.mast-more:focus-visible{outline:3px solid var(--yellow);outline-offset:3px;border-radius:var(--r-sm)}
.mast-more{width:24px;height:24px;border:0;background:none;color:#fff;padding:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center}
.mast-more svg{width:14px;height:14px;stroke:#fff;stroke-width:2;fill:none;transition:transform 200ms var(--sw)}
.mast-more[aria-expanded="true"] svg{transform:rotate(180deg)}

/* Sheets: a continuation of the bar, no shadow, no gap. --x is the label's offset within .mast-in,
   written by site.js. */
/* Removing Philanthropy Council from NAV (7 Sep 2026) took this sheet from 3 items to 2 and
   exposed that it was never actually forced to a vertical stack: with only two rows it rendered
   as a short, wide, side-by-side pair instead of a dropdown list. display:block on both the
   list and its rows, explicitly, closes off whatever the count-dependent layout was. */
/* Scoped inside .mast-nav deliberately, not left as a bare .mast-sheet: it has to outrank any
   nav-wide `ul`/`li` rule, or this silently collapses back into a horizontal strip again. */
.mast-nav .mast-sheet{display:block;position:absolute;top:100%;left:calc(var(--x,0px) - 20px);width:260px;margin:0;padding:8px 0 10px;list-style:none;
  background:var(--plan-blue);border-radius:0 0 var(--r) var(--r);
  opacity:0;transform:translateY(-6px);visibility:hidden;
  transition:opacity 180ms var(--sw),transform 180ms var(--sw),visibility 0s linear 180ms}
.mast-nav .mast-sheet li{display:block;gap:0}
.mast-nav .mast-sheet.open{opacity:1;transform:none;visibility:visible;transition:opacity 180ms var(--sw),transform 180ms var(--sw),visibility 0s}
a.mast-sheet-item{display:flex;align-items:center;gap:12px;padding:10px 20px;color:#fff;text-decoration:none;font:600 15px/1.2 'Poppins',Arial,sans-serif}
a.mast-sheet-item:hover,a.mast-sheet-item:focus{background:rgba(255,255,255,.1)}
a.mast-sheet-item:focus-visible{outline:3px solid var(--yellow);outline-offset:-3px}
a.mast-sheet-item.is-current::before{content:"";flex:none;width:22px;height:3px;border-radius:999px;background:var(--yellow)}

/* The right cluster: Start giving (Plan's own pill, its 44px radius kept from the fenced rule)
   and, below 1100, the menu button. */
.mast-right{display:flex;align-items:center;gap:12px;margin-left:28px;flex:none}
.mast .btn-donate{height:44px;padding:0 22px;gap:8px;font:700 15px/1 'Poppins',Arial,sans-serif;
  transition:height 240ms var(--sw),background .2s var(--sw),transform .16s var(--sw)}
.mast.is-condensed .btn-donate{height:44px}
.mast .btn-donate svg{width:15px;height:15px}
.mast-menu-btn{display:none;align-items:center;gap:10px;height:44px;min-width:44px;padding:0 4px;border:0;background:none;color:#fff;cursor:pointer}
.mast-menu-btn .bars{position:relative;width:22px;height:12px;display:block;flex:none}
.mast-menu-btn .bars i{position:absolute;left:0;right:0;height:2px;border-radius:999px;background:#fff;transition:transform .3s var(--sw),opacity .2s var(--sw)}
.mast-menu-btn .bars i:nth-child(1){top:0} .mast-menu-btn .bars i:nth-child(2){top:5px} .mast-menu-btn .bars i:nth-child(3){top:10px}
.mast-menu-btn[aria-expanded="true"] .bars i:nth-child(1){transform:translateY(5px) rotate(45deg)}
.mast-menu-btn[aria-expanded="true"] .bars i:nth-child(2){opacity:0}
.mast-menu-btn[aria-expanded="true"] .bars i:nth-child(3){transform:translateY(-5px) rotate(-45deg)}
.mast-menu-btn .lbl{font:700 15px/1 Arial,Helvetica,sans-serif}
.mast-menu-btn:focus-visible{outline:3px solid var(--yellow);outline-offset:3px;border-radius:var(--r-sm)}
.mast.menu-open .btn-donate{visibility:hidden}

/* The full-screen menu. Blue bar on blue menu is intended; the bar stays above it with the X. */
.mast-menu{position:fixed;inset:0;z-index:78;background:var(--plan-blue);color:#fff;
  padding:calc(var(--hdr) + 8px) 24px 0;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;
  opacity:0;transform:translateY(-8px);visibility:hidden;
  transition:opacity 260ms var(--sw),transform 260ms var(--sw),visibility 0s linear 260ms}
.mast-menu.open{opacity:1;transform:none;visibility:visible;transition:opacity 260ms var(--sw),transform 260ms var(--sw),visibility 0s}
html.no-js .mast-menu:target{opacity:1;transform:none;visibility:visible}
.mast-menu nav{flex:1 0 auto;width:100%;max-width:560px;margin:0 auto}
.mast-menu-word{display:none;margin:0 0 18px;font:700 13px/1.15 'Poppins',Arial,sans-serif;letter-spacing:.1em;text-transform:uppercase}
.mast-menu-list,.mast-menu-minor{list-style:none;margin:0;padding:0}
.mast-menu-list a{display:flex;align-items:center;height:56px;color:#fff;text-decoration:none;font:600 22px/1.1 'Poppins',Arial,sans-serif;border-bottom:1px solid rgba(255,255,255,.18)}
.mast-menu-list a:active{background:rgba(255,255,255,.08)}
.mast-menu-list a[aria-current="page"]{color:var(--yellow)}
.mast-menu-minor{margin-top:28px}
.mast-menu-minor a{display:flex;align-items:center;height:40px;color:rgba(255,255,255,.75);text-decoration:none;font:14px/1.2 Arial,Helvetica,sans-serif}
.mast-menu a:focus-visible{outline:3px solid var(--yellow);outline-offset:-3px}
.mast-menu-foot{position:sticky;bottom:0;margin:auto -24px 0;padding:16px 24px calc(16px + env(safe-area-inset-bottom));background:var(--plan-blue)}
.mast-menu-give{display:flex;align-items:center;justify-content:center;height:52px;border-radius:999px;background:var(--yellow);color:var(--ink);text-decoration:none;font:700 16px/1 'Poppins',Arial,sans-serif}
.mast-menu-give:focus-visible{outline:3px solid #fff;outline-offset:3px}
.mast-menu.open .mast-menu-list li{animation:mastItem 260ms var(--sw) both;animation-delay:calc(20ms * var(--i,0))}
@keyframes mastItem{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){
  header.mast,.mast-flag,.mast-div,.mast-word,.mast-nav a,.mast .btn-donate,.mast-sheet,.mast-menu,.mast-more svg{transition:none!important}
  .mast-menu.open .mast-menu-list li{animation:none!important}
}

/* Where the bar sits on each page shape (spec 2.1). --hdr is 14 + bar + 14. */
:root{--hdr:108px}
@media(max-width:1099px){ :root{--hdr:96px} }
@media(max-width:767px){ :root{--hdr:88px} }
html{scroll-padding-top:88px}
@media(max-width:1099px){ html{scroll-padding-top:84px} }
@media(max-width:767px){ html{scroll-padding-top:80px} }
body.mh-white{padding-top:var(--hdr)}
body.mh-band{padding-top:0}
body.mh-band .pg-masthead{padding-top:calc(var(--hdr) + clamp(64px,8vw,110px))}
body.mh-hero{padding-top:0}
.hero-editorial{min-height:100svh}

/* Tablet, 768 to 1099. */
@media(max-width:1099px){
  header.mast{height:68px} header.mast.is-condensed{height:72px}
  .mast-flag,.mast.is-condensed .mast-flag{height:38px} .mast-div,.mast.is-condensed .mast-div{height:30px} .mast-word,.mast.is-condensed .mast-word{font-size:12px}
  .mast-nav{display:none}
  .mast-right{margin-left:auto}
  .mast .btn-donate,.mast.is-condensed .btn-donate{height:40px;padding:0 18px;font-size:14px}
  .mast-menu-btn{display:inline-flex}
  .mast-menu-list a{font-size:24px}
}
/* Phone, below 768. */
@media(max-width:767px){
  header.mast{height:60px} header.mast.is-condensed{height:64px}
  .mast-in{padding:0 8px 0 12px}
  .mast-flag,.mast.is-condensed .mast-flag{height:30px}
  .mast-div,.mast.is-condensed .mast-div{height:26px;margin:0 8px} .mast-word,.mast.is-condensed .mast-word{font-size:9px}
  .mast .btn-donate,.mast.is-condensed .btn-donate{height:38px;padding:0 16px;font-size:14px} .mast .btn-donate svg{display:none}
  .mast-right{gap:8px}
  .mast-menu-btn{width:44px;padding:0;justify-content:center} .mast-menu-btn .lbl{display:none}
  .mast-menu-list a{font-size:22px}
}
@media(max-width:419px){
  .mast-div,.mast-word{display:none}
  .mast-menu-word{display:block}
}

/* 9 ── SECTION 3 COMPOSITION (spec 3, 6 Sep 2026): the small rules that let the page list be
   written as calls rather than inline styles. Headed paragraphs in a words column sit 28 apart;
   a pull figure hands to feature points at 40; an on_image band hands to a split at 64. */
.ls-body h3+p+h3{margin-top:var(--s3)}
.ls-body .pull-fig+.feature-points{margin-top:var(--s4)}
.lay-on+.lay-split{margin-top:var(--s5)}
.lay-overlap+.principles{margin-top:var(--s4)}
.sec-body>p.lead-in{margin:0 0 var(--s3);max-width:var(--measure)}
.ls-media .ls-cap{margin:var(--s2) 0 0;font-size:13.5px;line-height:1.5;color:var(--grey)}
.lay-split.is-rauto .ls-media img{max-width:300px;box-shadow:none;border-radius:0}  /* the lockup is a mark, not a photograph */
/* The 7/5 pair: a words column and an aside card (about #safeguarding). */
.lay-pair{display:grid;grid-template-columns:repeat(12,1fr);gap:clamp(24px,4vw,64px);align-items:start}
.lay-pair .lp-a{grid-column:span 7;min-width:0}
.lay-pair .lp-a .note{margin-top:var(--s3);max-width:none}
.aside-card{grid-column:span 5;background:var(--tint);border-radius:var(--r);padding:28px}
.aside-card .sec-eyebrow{margin:0 0 var(--s2)}
.aside-card .ac-mail{display:inline-block;font:700 20px/1.2 'Poppins',Arial,sans-serif;color:var(--plan-blue);text-decoration:none;overflow-wrap:anywhere}
.aside-card .ac-mail:hover{text-decoration:underline;text-underline-offset:4px}
.aside-card p{margin:var(--s2) 0 0;font-size:15.5px;line-height:1.6;color:var(--ink)}
/* The overlap card on a tinted or deep band inverts (home #mission is .alt, programmes #leadership .band-alt). */
.band-alt .lay-overlap .lo-card,.alt .lay-overlap .lo-card{background:var(--plan-blue-deep);color:#fff}
.band-alt .lay-overlap .lo-card p,.alt .lay-overlap .lo-card p{color:rgba(255,255,255,.86)}
.lay-overlap .lo-card{padding:var(--s4)}
@media(max-width:860px){ .lay-overlap .lo-card{padding:28px} }
.lay-overlap .lo-card .sec-eyebrow{color:#fff;margin:0}
.lay-overlap .lo-card h3{font-size:26px;line-height:1.15;margin:var(--s2) 0}
.lay-overlap .lo-card .dd-link{color:#fff;margin-top:var(--s2)}
/* The two short deep mastheads (3.2): endowment and give open on a single line each. */
body.mh-band .pg-masthead--short{padding:calc(var(--hdr) + clamp(48px,5.5vw,72px)) 0 clamp(48px,5.5vw,72px)}
.pg-masthead.pg-masthead--short h1{font-size:clamp(38px,4vw,58px)}  /* doubled: beats .pg-masthead h1, declared later at the same specificity */
.pg-masthead.pg-masthead--short .sec-intro{font-size:18px}
/* ── CLOSING STRIP (3.1), moved into the shared region so the homepage carries the same object. */
.cta-close{padding:clamp(40px,4.4vw,56px) 0 clamp(44px,5vw,64px)}
/* Matthew, 7 September: "just having it white for no reason doesn't make any sense... there's
   no purpose to this design." Correct, and the class name was the giveaway: this was called a
   card while having none of the properties of one. It had a 3px yellow hairline and top
   padding, and nothing else, so on a white page it wasn't an object at all, just text sitting
   under a stray line, immediately above a next-band that IS a real card. It's now an actual
   surface: the pale brand tint already used on the white mastheads (not a new colour invented
   for it), the site's own 16px corner radius, and padding on all four sides instead of only
   the top. The yellow edge stays, but now it's a deliberate cap on a real object rather than a
   line floating in white space. Tint rather than another block of deep blue on purpose: the
   next-band directly below it is deep blue, and two solid blue slabs stacked would read as one
   repeated thing rather than two different invitations. */
.cta-card{border-top:4px solid var(--yellow);background:var(--tint);border-radius:var(--r);
  padding:clamp(24px,2.8vw,34px) clamp(24px,3vw,40px) clamp(26px,3vw,38px);
  display:flex;align-items:center;justify-content:space-between;gap:clamp(20px,3vw,44px);flex-wrap:wrap}
.cta-line{font-family:'Poppins',Arial,sans-serif;font-weight:600;
  font-size:clamp(20px,2.1vw,27px);line-height:1.22;letter-spacing:-.01em;
  color:var(--ink);margin:0;max-width:19em;flex:1 1 320px}
.cta-actions{display:flex;flex-wrap:wrap;gap:12px;margin:0;flex:0 0 auto}
.cta-actions .btn{margin:0}
.cta-card.has-head{display:grid;grid-template-columns:repeat(12,1fr);column-gap:clamp(24px,2.4vw,40px);row-gap:0;align-items:start}  /* row-gap 0: the card's flex gap was becoming a 43px row gap */
.cta-card.has-head h2{grid-column:1/span 6;grid-row:1;font-size:28px;line-height:1.15;margin:0;max-width:none}
.cta-card.has-head .cta-line{grid-column:1/span 6;grid-row:2;margin-top:var(--s2);max-width:none;font-size:clamp(17px,1.4vw,20px);font-weight:400;font-family:Arial,Helvetica,sans-serif;line-height:1.5}
.cta-card.has-head .cta-actions{grid-column:8/span 5;grid-row:1/span 2;justify-content:flex-end;align-self:start}
@media(max-width:720px){
  .cta-card{align-items:flex-start}
  .cta-actions{width:100%}
  .cta-actions .btn{width:100%;justify-content:center}
  .cta-card.has-head{display:block}
  .cta-card.has-head .cta-actions{margin-top:var(--s3)}
}
/* ── NEXT BAND (3.1): typographic, no picture. Moved into the shared region for the homepage. */
/* Matthew flagged this same box twice: 6 September on the old two-column shape (a kicker and
   blurb on the left, the destination's title alone in a wide empty column on the right), then
   again 7 September after the first fix just made that empty box bigger by raising its
   max-width, with nothing new to fill the width it gained. Both times the actual fault was a
   single block-stacked text column, which stays exactly as narrow as its longest line
   regardless of how wide the box around it is allowed to be. The fix this time changes what
   the row IS, not how wide it is: text keeps a comfortable reading measure on the left, and a
   round arrow, a proper tap target rather than a small text link, anchors the right edge, so a
   wide card has a second thing to be wide FOR. The space between the two is doing the same job
   whitespace does between a kicker and a headline anywhere else on the site: it isn't empty,
   it's the gap that lets each side read as its own element. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* THE CLOSING PAIR. Matthew, 7 September: "put these beside each other so they're two columns
   ... they match the same height and width and everything. One is this colour, one is the dark
   blue." The closing CTA and the Next panel used to be two full-width sections stacked on each
   other, so every page ended on two long horizontal slabs. They are one row now: equal columns,
   equal height (stretch, plus height:100% so each fills its cell whatever its content), the
   same 16px corner and the same padding. The only difference between them is colour, which is
   the point: same object, two jobs. Below 860 they stack, because two half-width cards on a
   phone would be two cramped ones. */
/* Top padding is the CTA's, not the Next band's. The two sections this replaced had different
   top paddings (the CTA 40-56px, the Next band 0, because the CTA above it supplied the gap), and
   the first version of the pair took the Next band's, so the row sat flush against the tinted
   band above it. Matthew: "why is it right on the line?" This is why. */
.close-pair{padding:clamp(40px,4.4vw,56px) 0 clamp(44px,6vw,72px)}
.close-pair .cp{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(18px,2.2vw,30px);align-items:stretch}
.close-pair .cta-card{height:100%;margin:0;padding:clamp(24px,2.6vw,32px);box-sizing:border-box}
.close-pair .next-link{height:100%;margin:0;max-width:none;padding:clamp(24px,2.6vw,32px);box-sizing:border-box}
/* At half width the arrow needs less room around it than it does across a full-width band. */
.close-pair .next-go{width:clamp(46px,4vw,56px)}
@media(max-width:860px){
  .close-pair .cp{grid-template-columns:minmax(0,1fr)}
}
.next-band{padding:0 0 clamp(44px,6vw,72px)}
.next-link{display:flex;align-items:center;justify-content:space-between;gap:clamp(24px,4vw,56px);
  max-width:78em;
  background:var(--plan-blue);border-radius:var(--r);color:#fff;text-decoration:none;
  padding:clamp(32px,4vw,48px)}
.next-link:hover{background:var(--plan-blue-dk)}
.next-link:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}
.next-copy{max-width:30em}
.next-k{display:flex;align-items:center;gap:10px;font:700 13px/1 'Poppins',Arial,sans-serif;letter-spacing:.1em;text-transform:uppercase;color:#fff}
.next-k::before{content:"";flex:none;width:22px;height:3px;border-radius:999px;background:var(--yellow)}
.next-t{display:block;margin-top:var(--s2);font:700 clamp(28px,3vw,40px)/1.1 'Poppins',Arial,sans-serif;letter-spacing:-.015em;color:#fff}
.next-b{display:block;margin-top:var(--s2);font:18px/1.5 Arial,Helvetica,sans-serif;color:rgba(255,255,255,.86)}
/* The round "Read on": the words moved into the link's accessible name (an .sr-only span
   alongside the hidden svg) so a screen reader still hears "Next, Why girls, ..., Read on" as
   one sentence, while sighted users get the arrow, the more standard way to say "next". */
.next-go{flex:none;display:flex;align-items:center;justify-content:center;
  width:clamp(52px,6vw,68px);aspect-ratio:1;border-radius:50%;
  background:rgba(255,255,255,.16);color:#fff;
  transition:background var(--m-hover) var(--sw),transform var(--m-hover) var(--sw)}
.next-go svg{width:38%;height:38%;transition:transform var(--m-hover) var(--sw)}
.next-link:hover .next-go,.next-link:focus-visible .next-go{background:var(--yellow);color:var(--ink)}
.next-link:hover .next-go svg,.next-link:focus-visible .next-go svg{transform:translateX(3px)}
@media(max-width:640px){
  .next-link{padding:28px;gap:16px}
}

/* Spec 1.2: button hover is colour and a 1px lift, no shadow anywhere on a control. Overrides brand.css 40. */
.btn-primary:hover{box-shadow:none;transform:translateY(-1px)}

.gp-appeal{margin:0 0 8px;font:700 11px/1.3 'Poppins',Arial,sans-serif;letter-spacing:.08em;
  text-transform:uppercase;color:var(--plan-blue)}


/* ── THE PAYMENT FORM STAYS ON THE PAGE (Matthew, 6 September 2026) ─────────────────────────
   "Can we still put Apple Pay, the Link, and Amazon Pay in there? I don't want to be using a
   hosted page from Stripe. I want to use our own page... everything stays within that area."

   Three steps inside the one panel, shown one at a time by data-step on #gv-form: choose (the
   fields that already existed, plus an email for the receipt), pay (Stripe's own Payment
   Element, mounted here once a gift is chosen, showing whichever of card, Apple Pay, Amazon Pay
   and Link the browser and the Stripe account support) and done (a plain thank you, no
   navigation). Nothing here names a payment method in the markup: what shows is decided by
   Stripe and the dashboard's own settings, so it can change without a code change.

   Every element a step shows or hides is toggled by the `hidden` attribute alone, and none of
   the classes below sets `display` on that same element, only on its children: `display` on the
   hidden element itself would out-rank `[hidden]{display:none}` in the cascade and the step
   would not hide. */
.gp-pay-summary{margin:0 0 16px;font-size:15px;font-weight:700;color:var(--ink)}
#gv-payment-element{margin-bottom:14px;min-height:44px}
.gp-pay-error{margin:0 0 14px;padding:11px 14px;border-radius:var(--r-sm);
  background:#FDECEC;color:#8A1F1F;font-size:14px;line-height:1.4}
.gp-pay-actions{display:flex;gap:12px;align-items:center}
.gp-pay-actions .gp-cta{flex:1}
/* font:inherit here was resetting a REAL <button> (Pay) to whatever font-weight its parent
   happens to have, wiping out the bold Poppins that .gp-cta's own rule (line 656) sets, found
   live 6 Sep 2026. The Give button never showed this because it's an <a>, which this selector
   doesn't touch, so only Pay looked thin. Stating the same font here that .gp-cta already
   declares, rather than inheriting, makes button.gp-cta and a.gp-cta render identically again. */
button.gp-cta{border:0;cursor:pointer;appearance:none;-webkit-appearance:none;
  font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:16.5px}
button.gp-cta[disabled]{opacity:.55;cursor:default}
.gp-back{border:0;background:none;padding:12px 4px;font-family:'Poppins',Arial,sans-serif;
  font-weight:700;font-size:15px;color:var(--ink);cursor:pointer;text-decoration:underline;
  text-decoration-color:var(--grey);text-underline-offset:3px}
/* Neither of the next two had a rule of its own either, same browser-default-blue gap. */
.gp-back:focus-visible{outline:3px solid var(--yellow);outline-offset:2px}
.gp-email{width:100%;height:52px;border-radius:var(--r-sm);border:1.5px solid var(--grey);
  padding:0 16px;font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:15px;
  color:var(--ink);background:#fff}
.gp-email:focus-visible{outline:3px solid var(--yellow);outline-offset:2px}
.gp-email:invalid:not(:placeholder-shown){border-color:#C0392B}
.gp-email-note{margin:8px 0 0;font-size:12.5px;color:var(--mute)}
.gp-done-title{margin:0 0 8px;font-size:26px;font-weight:800;color:var(--ink)}
.gp-done-body{margin:0;font-size:15.5px;line-height:1.5;color:var(--ink)}
.gp-done-fields{padding:12px 0 4px}

/* SHARED-WITH-HOME END */

/* ── PANEL B: NAVIGATION. Poppins white on Plan Blue: one flat list of every page, each item a
   real link at the same size. It used to be four buttons with circular chevrons that expanded
   sub-lists; the buttons went nowhere, and three real pages sat below them in small type. A
   menu's job is to reach the pages, so it now does exactly that and nothing else.
   Each row carries a hairline and an arrow that slides on hover, so a row still reads as a
   destination without a control on it that does something different from the row itself. */
.np-item{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:14px 0;color:#fff;text-decoration:none;
  border-bottom:1px solid rgba(255,255,255,.22);
  font-family:'Poppins',Arial,sans-serif;font-weight:600;font-size:clamp(21px,2vw,25px);
  letter-spacing:-.01em;line-height:1.15;transition:padding-left .2s var(--sw)}
.np-item::after{content:"";flex:none;width:22px;height:22px;opacity:.55;
  background:no-repeat center/22px 22px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h13M13 6l6 6-6 6'/%3E%3C/svg%3E");
  transition:transform .2s var(--sw),opacity .2s var(--sw)}
/* padding-left ran a layout pass on twelve rows every frame; the walk moved to the arrow. */
.np-item:hover::after{transform:translateX(5px);opacity:1}
.np-item:focus-visible{outline:3px solid var(--yellow);outline-offset:3px;border-radius:var(--r-sm)}
.np-rule{border:0;border-top:1px solid rgba(255,255,255,.34);margin:22px 0 4px}
.np-minor{margin:0;padding:0;list-style:none;display:flex;flex-wrap:wrap;gap:6px 22px}
.np-minor a{display:block;padding:5px 0;color:rgba(255,255,255,.82);text-decoration:underline;
  text-underline-offset:4px;font-size:15.5px}
.np-minor a:hover{color:#fff}

/* Phones: the giving controls stay full size, because the standing rule is that buttons are the
   same size on every screen. The header's own phone rules live with the header, above. */
@media(max-width:560px){
  .gp-row.four{grid-template-columns:repeat(4,1fr);gap:6px}
  .gp-row.four .gp-opt span{font-size:12.5px;padding:0 2px}
}
.btn:focus-visible,.ph-logo:focus-visible,.np-minor a:focus-visible,footer.plan a:focus-visible{
  outline:3px solid var(--yellow);outline-offset:3px;border-radius:var(--r-sm)}
@media(prefers-reduced-motion:reduce){
  .panel,.hdr-scrim,.np-item,.bars i,.pill,.gp-cta{transition:none}
}

/* ── THE HERO EXPANDS ────────────────────────────────────────────────────────────────────────
   Matthew, 10 August: "I like how the image in the background gets larger, or that video starts
   to expand and fill the space. I want us to do that."

   At rest the hero is an inset card with a large radius, which is how plansverige.org frames its
   hero video (measured: 12px of inset each side of a 1200px viewport). As you scroll into it the
   inset and the radius both run to zero and the photograph grows, so the picture expands to fill
   the screen. --hp is the progress, 0 at rest and 1 fully expanded, written by the scroll handler.

   clip-path rather than margins or width: it costs no layout, so nothing inside the hero reflows
   while it animates and the headline never rewraps mid-scroll. */
/* Matthew, 6 September 2026: "the hero section should not go behind the menu. It needs to have
   a bit of space between the bottom of the menu and the image, the same amount that's on the
   right and left, so it looks balanced. It should be like a card unto itself." At rest the
   header's own --hdr already IS "14px above the bar, the bar, 14px below it" (spec 2.1), so
   clipping the hero's top edge to --hdr rather than the flat --inset used on the other three
   sides lands the photograph exactly one gap below the floating bar, the same gap it keeps on
   the sides, at every width the bar has (it changes at the same breakpoints --hdr does, so nothing
   here needs its own media queries). The photograph itself is untouched; only how much of it
   shows is clipped, the same technique the expansion below already relies on. */
.hero-editorial{--hp:0;
  clip-path:inset(calc((1 - var(--hp)) * var(--hdr)) calc((1 - var(--hp)) * var(--inset))
    calc((1 - var(--hp)) * var(--inset)) calc((1 - var(--hp)) * var(--inset))
    round calc((1 - var(--hp)) * var(--r)))}
.hero-editorial .bg{transform:scale(calc(1 + var(--hp) * .07));transform-origin:50% 40%}

/* The same idea once more, on the one editorial photograph further down: it settles from
   slightly oversize to true as it arrives, on plansverige's signature curve, which I measured on
   their teaser images (1s cubic-bezier(.34,.34,.02,.97)). */
/* The clip goes on a wrapper around the photograph, NOT on .feature-media. overflow:hidden on
   .feature-media clipped the two corner devices out of existence, because they are pseudo-
   elements offset 16px OUTSIDE the box. Matthew asked for them to be rounded, not removed. */
.fm-clip{position:absolute;inset:0;overflow:hidden;border-radius:var(--r);z-index:1}
.fm-clip img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* ── OUR IMPACT: the numbers, the reports row, the annual report cover ───────────────────────
   Page-specific, deliberately OUTSIDE the SHARED-WITH-HOME region: the homepage has its own
   stats band and carries none of these components, so nothing here must travel there. */

/* The thematic figures lead the page, so they take a display tier above the section tier.
   Sized for the longest figure, 5,200,000, to hold one line in a four-column stat. */
#numbers .stat .n{font-size:clamp(40px,4.2vw,64px)}

/* THE REPORTS SHELF (spec 6, our-impact #reports). Documents only: the cover is the card, the same
   object as the #annual cover, five in a row that scrolls in real pixels with dots and arrows the
   script adds. No script: the controls stay hidden, the viewport shows a thin scrollbar, all five
   read. Outside SHARED-WITH-HOME on purpose: the homepage has no shelf. */
.lay-shelf{--gap:clamp(24px,2.4vw,40px);--per:4;position:relative}
@media(max-width:1199px){ .lay-shelf{--per:3} }
@media(max-width:899px){ .lay-shelf{--per:2} }
@media(max-width:599px){ .lay-shelf{--per:1} }
.sh-viewport{overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;scrollbar-width:thin;padding-bottom:6px}
.lay-shelf.is-ready .sh-viewport{scrollbar-width:none}
.lay-shelf.is-ready .sh-viewport::-webkit-scrollbar{display:none}
.sh-track{display:grid;grid-auto-flow:column;grid-auto-columns:calc((100% - (var(--per) - 1) * var(--gap)) / var(--per));gap:var(--gap);list-style:none;margin:0;padding:0}
.sh-item{scroll-snap-align:start;scroll-snap-stop:always;min-width:0}
.sh-link,.sh-body{display:block;color:inherit;text-decoration:none}
.sh-link:focus-visible{outline:3px solid var(--yellow);outline-offset:3px;border-radius:var(--r-sm)}
/* THE REPORT COVERS, to the 7 September design handoff.
   The handoff's canvas is 460x613 with a 34px inset, a 52px title and a 15px standfirst. Those
   are ratios, not fixed sizes: the same cover is drawn at ~284px in the shelf and ~340px beside
   the annual report, so everything below is expressed as a share of the cover's own width
   (34/460 = 7.4cqw, 52/460 = 11.3cqw, and so on) and the drawing holds its proportions at any
   size. Container units are used ONLY on descendants of the cover, never on the cover's own
   properties: a container cannot query itself, and doing that is exactly what silently rendered
   this type at 1.1px before (see the note kept below). Each value also carries a px floor so a
   very narrow card degrades to legible rather than to nothing. */
.sh-cover{width:100%;aspect-ratio:460/613;border-radius:0;overflow:hidden;position:relative;
  container-type:inline-size;display:block;background:#0f2333;color:#fff;box-shadow:var(--shadow-1)}
.sh-shot{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
/* The scrim, verbatim from the handoff: dark under the lockup, open across the picture, and
   heavy from 78% down so the white type holds over any photograph. */
.sh-cover::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(15,35,51,.62) 0%,rgba(15,35,51,.05) 26%,rgba(15,35,51,.45) 52%,rgba(15,35,51,.95) 78%,rgba(15,35,51,.98) 100%)}
.sh-head{position:absolute;top:7.4cqw;left:7.4cqw;right:7.4cqw;z-index:2;
  display:flex;justify-content:space-between;align-items:flex-start;gap:8px}
.sh-logo{width:max(74px,30.4cqw);height:auto;display:block}
.sh-yr{font:600 max(9px,2.4cqw)/1 'Poppins',Arial,sans-serif;letter-spacing:.16em;color:#ffe000;flex:none}
.sh-block{position:absolute;bottom:7.4cqw;left:7.4cqw;right:7.4cqw;z-index:2;
  display:flex;flex-direction:column;gap:max(8px,3.5cqw)}
.sh-rule{width:max(28px,9.6cqw);height:max(3px,1.1cqw);background:#ffe000}
.sh-ct{font:800 max(23px,11.3cqw)/.98 'Poppins',Arial,sans-serif;letter-spacing:-.03em;color:#fff}
.sh-sf{font:400 max(11px,3.3cqw)/1.5 'Poppins',Arial,sans-serif;color:rgba(255,255,255,.88);max-width:71.7cqw}
.sh-hair{height:1px;background:rgba(255,255,255,.28)}
.sh-foot{display:flex;justify-content:space-between;gap:10px;
  font:600 max(8px,2.4cqw)/1.25 'Poppins',Arial,sans-serif;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.7)}
.sh-foot>span{white-space:nowrap}
/* The handoff's footer carries the report type AND the Foundation name on one line, which fits
   its 460px canvas but not the ~283px the shelf actually draws: at that width the two labels
   together need more room than the cover has, and both wrap to two ragged lines. The Foundation
   is already named by the lockup at the head of the cover, so on the narrower draw the second
   label simply steps aside rather than being crushed. It returns as soon as there is room. */
.sh-foot>span:last-child{display:none}
@container (min-width: 400px){ .sh-foot>span:last-child{display:block} }
/* KEPT AS A WARNING. Before the handoff, this cover sized its OWN padding in cqw. A container
   cannot query itself: per css-contain-3 those units resolved against the viewport instead, so
   at 1440 `padding:9cqw` became 129.6px a side, 259px of padding in a 284px card, collapsing the
   content box to 22.8px. The child text then queried the cover correctly against that 22.8px and
   computed to 1.96px. Invisible type in what looked like an empty box. Never put cqw on the
   cover itself; on its descendants, as above, it is correct and safe. */
@media(hover:hover){
  .sh-link .sh-cover{transition:transform 250ms var(--sw),box-shadow 250ms var(--sw)}
  .sh-link:hover .sh-cover{transform:translateY(-4px);box-shadow:var(--shadow-2)}
}
/* One continuous hairline under the covers: each caption's rule reaches into the gaps. */
.sh-cap{border-top:1px solid var(--hairline);margin-inline:calc(var(--gap) / -2);padding:var(--s2) calc(var(--gap) / 2) 0;margin-top:var(--s2)}
.sh-item:first-child .sh-cap{margin-inline-start:0;padding-inline-start:0}
.sh-item:last-child .sh-cap{margin-inline-end:0;padding-inline-end:0}
.sh-k{display:block;font:700 13px/1 'Poppins',Arial,sans-serif;letter-spacing:.1em;text-transform:uppercase;color:var(--plan-blue);margin:0 0 var(--s1)}
.sh-cap h3{font-size:20px;line-height:1.2;margin:0 0 var(--s1);color:var(--ink)}
.sh-cap p{font-size:15.5px;line-height:1.55;color:var(--grey);margin:0}
.sh-state{font-size:13.5px;line-height:1.4;color:var(--ink);margin-top:var(--s2)!important;display:flex;align-items:center;gap:8px}
.sh-state.is-prep::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--yellow);flex:none}
.sh-cap .dd-link{display:inline-flex;margin-top:var(--s2);padding-top:0}
/* Controls: dots left, arrows right, 28 under the captions. */
/* Reports block (acf/ggf-reports), added 12 September 2026: the same cover/caption pieces above,
   laid out as a plain responsive grid instead of the carousel — see the doc comment at the top of
   blocks/reports.php for why. .is-plain drops the carousel cover's text-on-photo scrim, since this
   version never draws text over the picture at all. */
.ggf-reports{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(24px,2.4vw,40px)}
@media(max-width:1199px){ .ggf-reports{grid-template-columns:repeat(3,1fr)} }
@media(max-width:899px){ .ggf-reports{grid-template-columns:repeat(2,1fr)} }
@media(max-width:599px){ .ggf-reports{grid-template-columns:1fr} }
.ggf-report-card{display:block;color:inherit;text-decoration:none}
.sh-cover.is-plain::after{display:none}
.ggf-report-card .sh-cap{border-top:1px solid var(--hairline);padding-top:var(--s2);margin-top:var(--s2)}
@media(hover:hover){
  .ggf-report-card .sh-cover{transition:transform 250ms var(--sw),box-shadow 250ms var(--sw)}
  .ggf-report-card:hover .sh-cover{transform:translateY(-4px);box-shadow:var(--shadow-2)}
}
.sh-ctl{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 16px;margin-top:var(--s3)}  /* wraps at 320, where five dots and two arrows outrun the wrap */
.sh-dots{display:flex;gap:0}
.sh-dot{width:44px;height:44px;border:0;background:none;padding:0;display:grid;place-items:center;cursor:pointer}
.sh-dot i{display:block;width:10px;height:10px;border-radius:999px;background:var(--keyline);transition:width 250ms var(--sw),background-color 250ms var(--sw)}
.sh-dot[aria-current="true"] i{width:28px;background:var(--plan-blue)}
.sh-dot:focus-visible{outline:3px solid var(--yellow);outline-offset:-4px;border-radius:var(--r-sm)}
.sh-arrows{display:flex;gap:8px}
.sh-arrows .ctl{width:44px;height:44px;border-radius:50%;border:1.5px solid var(--plan-blue);background:#fff;color:var(--plan-blue);display:grid;place-items:center;cursor:pointer;padding:0}
.sh-arrows .ctl svg{width:20px;height:20px}
.sh-arrows .ctl.sh-prev svg{transform:scaleX(-1)}
.sh-arrows .ctl:hover{background:var(--plan-blue);color:#fff}
.sh-arrows .ctl:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}
.sh-arrows .ctl[aria-disabled="true"]{opacity:.35;pointer-events:none}
.sh-live{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@media(max-width:599px){
  .sh-cover{max-width:240px}
  .sh-dot{width:36px;height:36px;margin-right:4px}
}
@media(prefers-reduced-motion:reduce){
  .sh-link .sh-cover,.sh-dot i{transition:none}
  .sh-link:hover .sh-cover{transform:none;box-shadow:var(--shadow-1)}
}

/* THE ANNUAL REPORT COVER. No report exists yet, so the cover is built from the site's own
   devices rather than a mock image: Plan Blue ground, the Poppins display tier, the yellow
   circle the mastheads already carry, A4 proportions. Solid white on Plan Blue for the text;
   the year sits in yellow at display size. Radii from the shape gate: 16px card, 50% circle. */
/* Same fix as .lay-split/.qa-echo, same reason: the text column (a paragraph and three
   checklist items) is naturally shorter than the report cover beside it, and top-aligning
   both left a bare gap under the text instead of the two reading as a balanced pair, found
   live 7 Sep 2026. */

@media(prefers-reduced-motion:reduce){
  .hero-editorial{clip-path:none}
  .hero-editorial .bg{transform:none}
  .fm-clip img{transform:none;transition:none}
}


/* ── INNER PAGE MASTHEAD ─────────────────────────────────────────────────────────────────────
   The first pass set page titles at 56px on plain white, only 1.33x the section headings below,
   so no page had a top and every page read as a stack of equal blocks. Now: a full-bleed tint
   band, the homepage's own display tier, and room to breathe. When a masthead carries an image,
   the type takes cols 1-7 and the photograph fills the right. */
.pg-masthead{padding:clamp(64px,8vw,110px) 0 clamp(44px,5.5vw,72px);background:var(--tint)}
.pg-masthead h1{font-size:clamp(42px,5.2vw,74px);line-height:1.14;letter-spacing:-.02em;
  max-width:13em;margin:0 0 20px;color:var(--ink)}
/* The underpaint that used to live here has gone. It was written to stop a solid highlight
   colliding with the line above, which was the right diagnosis and the wrong cure: it made the
   masthead a SECOND device under the same class name, so the homepage got a highlighter and
   every inner page got a thick underline, both called .hl. The marker in the shared block above
   paints a fixed band instead of the font's content box, which solves the collision at every
   size without needing a second device. */
.pg-masthead .sec-intro{max-width:34em;margin-bottom:0;font-size:clamp(17px,1.45vw,20px)}
.pg-masthead .wrap{display:grid;grid-template-columns:repeat(12,1fr);gap:18px;align-items:start}
/* Matthew, on the Partner masthead: "needs redesigning and fixing." This is the same fault
   already fixed three times on this site (.lay-split, .qa-echo, .ar): align-items:start pins a
   short column to the top of a row whose height is set by a taller one, so the copy floated at
   the top with ~120px of dead white beneath it while the photograph ran on. Scoped to has-img
   so text-only mastheads, where there is no second column to balance against, are untouched. */
.pg-masthead.has-img .wrap{align-items:center}
.pg-masthead .mh-copy{grid-column:1/span 12}
.pg-masthead.has-img .mh-copy{grid-column:1/span 7}
.pg-masthead .mh-img{display:none}
.pg-masthead.has-img .mh-img{display:block;grid-column:9/span 4;position:relative}
.pg-masthead .mh-img img{width:100%;aspect-ratio:4/5;object-fit:cover;border-radius:var(--r);display:block}
@media(max-width:860px){
  .pg-masthead.has-img .mh-copy{grid-column:1/span 12}
  .pg-masthead.has-img .mh-img{grid-column:1/span 8;margin-top:26px}
}


/* The cards-connected fix was scoped to #mission, so the same strip on any other page rendered
   with the original fault: rounded cells butted at 0px inside a square frame, which leaves a
   wedge at every join. This is the same rule, available to any page that uses the strip. */
.themes--cards{border:0;gap:18px;align-items:stretch}
/* :last-child is not decoration here, it is the fix for the fault Matthew spotted himself:
   "There's something wrong with the Girls in Leadership box on the right. It's been cut off."
   brand.css line 150 carries `.themes .cell:last-child{border-right:none}` from an older design
   where the cells shared one bordered rail, so the last card in this variant rendered with three
   borders and an open right-hand side. Two classes plus a pseudo-class beat two classes, which
   is why restating the border on .themes--cards .cell alone never took. */
.themes--cards .cell,.themes--cards .cell:last-child{border:1.5px solid var(--grey);border-radius:var(--r);height:100%}
.themes--cards .flag{border-color:var(--plan-blue)}
@media(max-width:820px){ .themes--cards{grid-template-columns:1fr} }


/* ── THE INNER-PAGE DESIGN SYSTEM ────────────────────────────────────────────────────────────
   Matthew, 11 August: "It's just text... no imagery. There's no engagement... It needs to seem
   highly designed, but still make sure that everything we do can be done through CSS."
   Every device below is plain markup plus CSS. The only JavaScript on these pages is the giving
   widget and the reveal-on-scroll helper, and the reveals also run without it on new browsers
   via the scroll-driven animation block at the end. */

/* Duotone photography: any image becomes a brand object with two declarations, which is exactly
   the kind of treatment a locked CMS allows, because it needs no edited asset. */
.duo{position:relative;overflow:hidden;border-radius:var(--r)}
.duo img{width:100%;height:100%;object-fit:cover;display:block;filter:grayscale(1) contrast(1.06)}
.duo::after{content:"";position:absolute;inset:0;border-radius:var(--r);
  background:linear-gradient(160deg,rgba(0,114,206,.82),rgba(10,42,67,.88));mix-blend-mode:multiply}

/* The image band: a full-width photograph carrying one claim, between text sections, so a page
   is never two screens of type in a row. */
.img-band{position:relative;border-radius:var(--r);overflow:hidden;min-height:340px;display:flex;
  align-items:flex-end}
.img-band > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* The first scrim ran corner-to-corner at 15deg, so the TOP lines of a multi-line claim sat on
   .2 alpha and dissolved into bright photographs. This one darkens the text COLUMN, full height,
   and leaves the right of the image open. */
/* z-index:1 is the fix that makes this exist at all: both the img and this pseudo-element are
   absolutely positioned with z-index auto, and the pseudo-element paints FIRST in tree order,
   so without it the photograph covers the gradient and white copy sits on raw photo. Round 2
   caught that the round-1 "fix" had never rendered. */
.img-band::before{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(90deg,rgba(10,42,67,.88) 0%,rgba(10,42,67,.6) 45%,rgba(10,42,67,.08) 100%)}
.img-band .band-copy{z-index:2}
.img-band .band-copy{position:relative;z-index:1;padding:clamp(26px,4vw,46px);max-width:30em}
.img-band .band-copy p{color:#fff;font-family:'Poppins',Arial,sans-serif;font-weight:600;
  font-size:clamp(21px,2.2vw,30px);line-height:1.25;letter-spacing:-.01em;margin:0}
/* the caption lives BELOW the band now; on the photo it was illegible on every image */
.band-note{margin:10px 2px 0;font-size:12.5px}
.img-band .band-copy p::before{content:"";display:block;width:22px;height:3px;border-radius:999px;
  background:var(--yellow);margin-bottom:16px}

/* The pull figure: one number given the floor, the site's stat device at section scale. */
/* align-items:baseline was lining up the number's OWN baseline with the paragraph's first
   line, but the number runs 52-88px against the paragraph's 16.5px, so its cap-height towers
   far above the text next to it instead of the two looking balanced, found live 7 Sep 2026.
   flex-start lines up both elements' top edges instead. */
.pull-fig{display:flex;flex-wrap:wrap;align-items:flex-start;gap:18px;border-top:4px solid var(--plan-blue);
  padding-top:22px;max-width:46em}
.pull-fig .n{font-family:'Poppins',Arial,sans-serif;font-weight:700;color:var(--plan-blue);
  font-size:clamp(52px,6vw,88px);line-height:.95;letter-spacing:-.02em}
.pull-fig p{font-size:16.5px;max-width:22em;color:var(--ink);margin:0}

/* QUESTIONS DONORS ASK (spec 7.2, 7.3, 7.4). The page is a 12-column body of its own: a sticky rail
   in cols 1 to 3 and the groups in cols 5 to 12; every question open, with its source line, so
   Ctrl-F, print and an adviser's skim all work. The echo lists on five pages render the same data. */
.qa .qa-grid{display:block}
.qa-rail .sec-eyebrow{margin:0 0 var(--s2)}
.qa-rail ul{list-style:none;margin:0;padding:0;border-left:3px solid var(--hairline)}
.qa-rail a{display:block;padding:8px 0 8px 14px;margin-left:-3px;border-left:3px solid transparent;text-decoration:none;
  font:600 15px/1.3 'Poppins',Arial,sans-serif;color:var(--ink);transition:color 200ms var(--sw),border-color 200ms var(--sw)}
.qa-rail a:hover{color:var(--plan-blue)}
.qa-rail a:focus-visible{outline:3px solid var(--yellow);outline-offset:2px;border-radius:var(--r-sm)}
.qa-body{margin-top:var(--s4)}
.qa-group{scroll-margin-top:112px}
.qa-group+.qa-group{margin-top:var(--s4)}
.qa-group .sec-eyebrow{margin:0}
.qa-group h2{font-size:28px;line-height:1.15;margin:var(--s2) 0 0;max-width:none}
.qa-group .qa-intro{font-size:18px;line-height:1.5;color:var(--grey);margin:var(--s2) 0 var(--s3);max-width:var(--measure)}
.qa-q{border-top:1px solid var(--hairline);padding:28px 0;scroll-margin-top:112px}
.qa-q h3{font-size:20px;line-height:1.25;margin:0 0 var(--s2);color:var(--ink)}
.qa-q p{font-size:15.5px;line-height:1.6;color:var(--ink);max-width:var(--measure);margin:0}
.qa-q p+p{margin-top:var(--s2)}
.qa-q .src,.faq .a .src{font-size:13.5px;line-height:1.5;color:var(--grey);margin-top:8px}
.qa-q .src a,.faq .a .src a{color:var(--plan-blue);text-decoration:underline;text-decoration-color:var(--yellow);text-underline-offset:3px}
a.figtag{text-decoration:none}
a.figtag:hover{text-decoration:underline}
.owed-list{list-style:none;margin:var(--s3) 0 0;padding:0}
.owed-list li{padding:8px 0;border-top:1px solid var(--hairline);font-size:15.5px;line-height:1.5;color:var(--ink);max-width:var(--measure)}
.owed-list li:last-child{border-bottom:1px solid var(--hairline)}
.qa-body>.faq-ask{margin-top:var(--s4)}
@media(min-width:1200px){
  .qa .qa-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:clamp(24px,2.4vw,40px);align-items:start}
  .qa-rail{grid-column:1/span 3;position:sticky;top:112px;align-self:start}
  .qa-rail a.is-active{color:var(--plan-blue);border-left-color:var(--yellow)}
  .qa-body{grid-column:5/span 8;margin-top:0}
  .qa-group+.qa-group{margin-top:var(--s5)}
}
/* Echo lists (7.4): three questions from one group, by reference, beside the tail line. */
.qa-echo-list{list-style:none;margin:0;padding:0;border-bottom:1px solid var(--hairline)}
.qa-echo-link{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:28px 0;border-top:1px solid var(--hairline);
  text-decoration:none;color:var(--ink);font:600 20px/1.25 'Poppins',Arial,sans-serif}
.qa-echo-link svg{flex:none;width:17px;height:17px;transition:transform 200ms var(--sw)}
.qa-echo-link:hover{color:var(--plan-blue)}
.qa-echo-link:hover svg{transform:translateX(4px)}
.qa-echo-link:focus-visible{outline:3px solid var(--yellow);outline-offset:3px;border-radius:var(--r-sm)}
.qa-echo .faq-ask{margin-top:var(--s3)}
@media(min-width:1200px){
  /* Same fix as .lay-split, same reason: a single tail-line link beside a 3-item question list
     left 270px of bare space under the link, found live on Endowment 6 Sep 2026. */
  .qa-echo{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:clamp(24px,2.4vw,40px);align-items:stretch}
  .qa-echo-list{grid-column:1/span 7}
  .qa-echo .faq-ask{grid-column:9/span 4;margin-top:0;display:flex;flex-direction:column;justify-content:center}
}
@media(prefers-reduced-motion:reduce){ .qa-rail a,.qa-echo-link svg{transition:none} }

/* CSS-only accordions, for the questions a donor actually asks. Native details/summary, so it
   works with JavaScript disabled and inside any CMS block that permits raw HTML. */
.faq{border-top:1px solid var(--hairline);max-width:46em}
.faq:last-of-type{border-bottom:1px solid var(--line)}
.faq summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;
  gap:18px;padding:18px 2px;font-family:'Poppins',Arial,sans-serif;font-weight:700;
  font-size:17px;color:var(--ink)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";flex:none;width:30px;height:30px;border-radius:50%;
  border:1.5px solid var(--grey);
  background:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230072CE' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center/16px no-repeat;
  transition:transform .3s var(--sw)}
.faq[open] summary::after{transform:rotate(180deg)}
.faq summary:hover{color:var(--plan-blue)}
.faq .a{padding:0 2px 20px;color:var(--grey);font-size:15.5px;line-height:1.62;max-width:40em}
.faq .a p{margin:0 0 10px}

/* The steps device: how a major gift actually happens, numbered, on the page's own rule. */
/* Spec 4: THE NUMBERED STEPS, two uses on the whole site, both bare. A Poppins numeral, no circle,
   no hairline, no track. The row (why-girls #theory) is a grid from 1200 with three hand-drawn
   connectors, the hero's own stroke, drawn on reveal; below 1200 and in the column (partner #how)
   it is a plain list with 28 between items. */
.steps{list-style:none;margin:0;padding:0;counter-reset:st}
.steps li{counter-increment:st;position:relative;min-width:0}
.steps li+li{margin-top:28px}
.steps li::before{content:counter(st,decimal-leading-zero);display:block;font:700 26px/1 'Poppins',Arial,sans-serif;color:var(--plan-blue);margin-bottom:var(--s2)}
.steps h3{font-size:20px;margin:0 0 var(--s1);color:var(--ink)}
.steps p{font-size:15.5px;color:var(--grey);margin:0;line-height:1.6}
/* Matthew, on the column variant (Partner, "How a significant gift actually happens"): "poorly
   designed use of space. This looks weird... maybe you need to find some other way of
   implementing this design." Two real faults. First, the number was a block element sitting on
   its own line above each heading, so four steps burned four whole lines on four numerals and
   the number was visually detached from the title it belonged to. Second, the row variant of
   this component draws a yellow line between its steps so the sequence reads as a sequence,
   and the column variant drew nothing, so it was four disconnected blocks that happened to be
   numbered. Now: the numeral sits in its own gutter beside the title it labels, and a rule runs
   down through the gutter linking each step to the next, which is the row variant's connector
   turned on its side. Only the Partner page uses is-col, so this touches nothing else. */
.steps.is-col{display:block;max-width:44em}
.steps.is-col li{display:grid;grid-template-columns:34px minmax(0,1fr);column-gap:16px}
.steps.is-col li+li{margin-top:0}
.steps.is-col li::before{grid-column:1;grid-row:1;margin:0;font-size:19px;line-height:1.35;
  text-align:right;font-variant-numeric:tabular-nums}
.steps.is-col h3{grid-column:2;grid-row:1}
.steps.is-col li>p{grid-column:2;grid-row:2;padding-bottom:26px}
.steps.is-col li:last-child>p{padding-bottom:0}
/* The connector: down the gutter, from under the numeral to the next one. Sits under the
   numerals (z-index) so a descender never collides with the line. */
.steps.is-col li:not(:last-child)::after{content:"";position:absolute;left:16px;width:2px;
  top:26px;bottom:8px;background:var(--yellow);border-radius:999px}
@media(min-width:1200px){
  .steps.is-row{display:grid;grid-template-columns:repeat(var(--n,4),minmax(0,1fr));column-gap:clamp(24px,2.6vw,44px)}
  .steps.is-row li+li{margin-top:0}
  /* Matthew, 8 September: "remove all the doodles... make it plain." This used to be a
     hand-drawn squiggle (first invented, later the real underline-soft.svg asset); it is a
     plain bar now, the same colour and the same device .steps.is-col already uses for its own
     connector, just wiping in on reveal rather than sitting static in the vertical layout. */
  .steps.is-row li:not(:last-child)::after{content:"";position:absolute;top:13px;height:4px;left:calc(2ch + 12px);right:calc(clamp(24px,2.6vw,44px) * -1 + 12px);
    background:var(--yellow);border-radius:999px;transform:scaleX(0);transform-origin:left}
  html.m-ready .steps.is-row.in li::after{transform:scaleX(1);transition:transform .8s var(--sw);transition-delay:calc(var(--m-i,0) * var(--m-stagger,80ms) + .3s)}
  html.no-js .steps li::after,html:not(.m-ready) .steps li::after{transform:scaleX(1)}
}
@media(prefers-reduced-motion:reduce){ .steps li::after{transform:scaleX(1)!important;transition:none!important} }
/* The account beside the picture on give #what-happens (spec 4 REPLACE 3). */
.ls-body .ls-h3{font-size:26px;line-height:1.15;letter-spacing:-.01em;margin:var(--s2) 0 var(--s3);color:var(--ink)}
/* The timed rows on thank-you (spec 4 REPLACE 6). */
/* Doubled class on purpose: at (0,2,1) these beat the base .fact-rows rules declared later at (0,1,1). */
.fact-rows.fact-rows--when>div{padding:28px 0}
.fact-rows.fact-rows--when dt{color:var(--plan-blue);font-size:18px}
.fact-rows.fact-rows--when dd{color:var(--ink)}
.fact-rows.fact-rows--when dd b{display:block;font:700 20px/1.2 'Poppins',Arial,sans-serif;color:var(--ink);margin-bottom:var(--s1)}
.pull-fig.is-bare{border-top:0;padding-top:0;margin-top:var(--s4)}

/* Named people: the device the board and the team share. */
/* auto-fit, not auto-fill: auto-fill keeps the empty tracks it made room for, so three Council
   members in a 1584px row sat in the first three of six columns with half the row left blank.
   auto-fit collapses the tracks nobody filled and the three share the width. */
/* .people / .person retired 5 Sep 2026 (spec 5.1): the register replaced every people grid. */

/* Section rhythm: alternate white and tint automatically so no page is one long white run. */
.band-alt{background:var(--paper-2)}

/* Legal pages: readable measure, real hierarchy, nothing clever. */
/* 760px was right when the page was one column of running text. It is now a rail plus the
   clauses, and this rule sits later in the file at the same specificity as the grid above, so
   left in place it squeezed the clause column to 282px. Narrow screens keep the single column
   and the reading measure; the wide layout sets its own width. */
@media(max-width:1199px){ .legal .wrap{max-width:760px} }
.legal h2{font-size:clamp(22px,2.2vw,28px);margin:38px 0 12px}
.legal p,.legal li{font-size:15.5px;line-height:1.7;color:var(--ink)}
/* Every other break on this page has a gap (38px before an h2, 44px either side of the <hr>,
   40px before the closing line): consecutive paragraphs with nothing between them, like the
   three Copyright-information clauses, did not, and ran together as one block, found live
   6 Sep 2026. */
.legal p+p{margin-top:16px}
.legal ul{padding-left:22px;margin:10px 0}

/* The scroll-driven reveal (the 20px, entry-ranged, transform-based version) and its
   reduced-motion reset both moved into the MOTION block inside SHARED-WITH-HOME, so the
   homepage gets them too. The new reset also clears `translate`, which this one did not:
   without that a reduced-motion reader saw every reveal visible but parked 10px low. */
@media (prefers-reduced-motion:reduce){
  .faq summary::after{transition:none}
}


/* The next band's rules live in the SHARED-WITH-HOME region now (spec 3.1). */


/* Board monograms: a face-shaped placeholder until portraits exist, honestly labelled. */


/* Deep links used to land with the section heading hidden under the 100px sticky header. */
/* [id]{scroll-margin-top:116px} removed: it ADDED to scroll-padding-top, so every
   in-page link landed its heading roughly 120px below the header. One mechanism now. */


/* ── ROUND 4 (Matthew, 11 August) ────────────────────────────────────────────────────────────
   "One footer block, not two", the dead air above the closing CTA, and variety: no two subpage
   mastheads identical, and fewer identical bullet lists. All of it CSS on plain markup. */

/* The rails' layout now lives with the rest of the footer, further down this file. */

/* ── THE CLOSING BLOCK ────────────────────────────────────────────────────────────────────────
   One designed object. The first attempt at the gap on About zeroed the top padding, which
   cured the dead air and created a collision: the buttons sat flush against the band above.
   The block now has measured space on both sides and a shape of its own, so it reads as the
   page's closing statement rather than as two buttons that fell out of the section above.
   Spacing chosen against the 89.6px section rhythm: 56px above (clearly separate from the band,
   clearly not a new section), 64px below (a beat before the Next panel, not a chasm). */
/* The closing strip's rules live in the SHARED-WITH-HOME region now (spec 3.1). */

/* Masthead variants, one per page, so no two subpages open identically. */
.pg-masthead--deep{background:var(--plan-blue-deep)}
.pg-masthead--deep h1,.pg-masthead--deep .sec-intro{color:#fff}
.pg-masthead--deep .sec-intro{color:rgba(255,255,255,.92)}
.pg-masthead--deep .sec-eyebrow{color:#fff}
.pg-masthead--white{background:#fff}
.pg-masthead--left.has-img .mh-copy{grid-column:6/span 7}
.pg-masthead--left.has-img .mh-img{grid-column:1/span 4;grid-row:1}
/* Matthew, 8 September: "this little yellow dot... make it plain." The masthead photo's
   corner-circle accent (.mh-img::before, the mirrored --left variant of the same mark) is gone;
   the photograph's own rounded corner is the only shape now. */
@media(max-width:860px){
  .pg-masthead--left.has-img .mh-copy{grid-column:1/span 12}
  .pg-masthead--left.has-img .mh-img{grid-column:1/span 8;grid-row:auto}
}

/* Device: definition rows. A term and its meaning on a hairline, for routes and policies,
   so not every list on the site is the same yellow-dash bullet. */
.fact-rows{margin:0;max-width:46em}
.fact-rows>div{display:grid;grid-template-columns:minmax(150px,220px) 1fr;gap:8px 26px;
  padding:16px 2px;border-top:1px solid var(--hairline)}
.fact-rows>div:last-child{border-bottom:1px solid var(--hairline)}
.fact-rows dt{font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:15.5px;color:var(--ink);margin:0}
.fact-rows dd{font-size:15px;color:var(--grey);margin:0;line-height:1.6}
@media(max-width:640px){ .fact-rows>div{grid-template-columns:1fr;gap:4px} }

/* Device: principle cards. Three short convictions in tint cards, for values content,
   instead of another checklist. */
.principles{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:var(--s4)}
.sec-body>.principles:first-child{margin-top:0}
.principles .pr{background:var(--tint);border-radius:var(--r);padding:22px 24px}
.principles h3{font-size:16.5px;margin:0 0 8px;color:var(--plan-blue)}
.principles p{font-size:14.5px;color:var(--ink);margin:0;line-height:1.55}
.principles .pr::before{content:"";display:block;width:22px;height:3px;border-radius:999px;
  background:var(--yellow);margin-bottom:12px}
@media(max-width:820px){ .principles{grid-template-columns:1fr} }


/* The search: a native details disclosure carrying a real site-scoped search form. It worked
   nowhere before, a button with no behaviour. No JavaScript involved. */
.ph-searchbox{position:relative}
.ph-searchbox summary{list-style:none;cursor:pointer;padding:6px;line-height:0;display:block}
.ph-searchbox summary::-webkit-details-marker{display:none}
.ph-searchbox summary svg{width:19px;height:19px;stroke:#fff}
.ph-searchbox[open] summary svg{stroke:var(--yellow)}
.ph-searchform{position:absolute;right:0;top:calc(100% + 14px);background:#fff;border-radius:var(--r);
  padding:10px;display:flex;gap:8px;width:320px;max-width:80vw}
.ph-searchform input[type="search"]{flex:1;border:1.5px solid var(--grey);border-radius:var(--r-sm);
  padding:10px 12px;font-size:15px;font-family:Arial,Helvetica,sans-serif;min-width:0}
.ph-searchform button{border:0;border-radius:var(--r-sm);background:var(--plan-blue);color:#fff;
  font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:14px;padding:0 16px;cursor:pointer}
.ph-searchform button:hover{background:var(--plan-blue-dk)}
.ph-searchform input:focus-visible,.ph-searchform button:focus-visible,.ph-searchbox summary:focus-visible{outline:3px solid var(--yellow);outline-offset:2px}
@media(max-width:1024px){ .ph-searchbox{display:none} }


/* The FAQ chevron answers the cursor before the click. */
.faq summary{transition:color .2s var(--ease)}
.faq summary::after{transition:transform .3s var(--sw),background .2s var(--ease)}
/* background-COLOR, not the shorthand: the shorthand resets background-image and erased the
   chevron arrow on hover, the exact opposite of the reward it was meant to be. */
.faq summary:hover::after{background-color:var(--tint)}

/* The theory of change: the connecting line draws itself in as each step arrives, so the causal
   chain visibly connects as you read it. Pure CSS, new browsers only, still guarded. */




/* ── ELEMENT SWEEP, 11 August (run in a real browser, measured not eyeballed) ────────────────
   Four findings, four fixes:
   1. two different label letter-spacings did the same job (.1em on panel labels, .14em on
      section eyebrows). One voice now.
   2. the Give button's 36px mobile height is under the 44px touch minimum. The visual stays
      Plan's 36px; the TAP AREA extends invisibly to 48px.
   3. .faq summary and the comments tab had no focus ring; everything else did.
   4. (verified fine, recorded so nobody re-checks: 89.6px section rhythm uniform, one card
      padding token, 42px h2s uniform, drawers full-bleed at 375px, chips 46px, no overflow.) */
.gp-q{letter-spacing:.14em}
@media(max-width:560px){
  .btn-donate{position:relative}
  .btn-donate::after{content:"";position:absolute;inset:-6px;border-radius:999px}
}
.faq summary:focus-visible{outline:3px solid var(--yellow);outline-offset:3px;border-radius:var(--r-sm)}
.rv-tab:focus-visible{outline:3px solid var(--yellow);outline-offset:3px}


/* ── THE REVIEW CHIP, corrected from the page ────────────────────────────────────────────────
   Matthew, 11 August: "The approve button has a white outline on the left, right, and bottom,
   but there's none on the top."
   Exactly right, and here is why: /system/approve.js sets border:1px solid #d7dee3 with
   border-top:4px solid #0072CE. Collapsed, the head fills Plan Blue, so the top border is blue
   on blue and disappears while the other three sides stay pale. An outline on three sides only.
   The fix belongs in approve.js, but git access is currently blocked, so it is corrected here
   with one extra specificity step, which is also exactly how it would be corrected on the
   locked WordPress platform. It also joins the site's rounded-shape system while we are here. */
html body .ggfa.min{border:0;border-radius:999px;overflow:hidden}
html body .ggfa.min .ggfa-head{border-radius:999px}
html body .ggfa{border-radius:var(--r);overflow:hidden}
/* the toggle's 44px hit area lives in the SHARED-WITH-HOME block, so the homepage gets it too */


/* The width and wide-state rules live in the SHARED-WITH-HOME block above, because the
   homepage keeps its own copy of this stylesheet and must get them too. */


/* ── THE FOOTER, CONDENSED ───────────────────────────────────────────────────────────────────
   Matthew: "we need to condense this footer way more. There's too much empty negative space."
   Measured before: 1165px tall, with a 512px block that was a nesting bug of mine (the rails
   wrapper never closed, so it swallowed the contact and newsletter blocks). Structure repaired,
   and every band tightened: the column gap 56 -> 40, the block rhythm roughly halved, and the
   contact and newsletter blocks now sit on the same row as the link columns rather than in
   their own storey. */
footer.plan{padding:clamp(34px,3.6vw,48px) 0 0}
footer.plan .ft-top{margin-bottom:18px}
footer.plan .ft-rule{margin:20px 0}
footer.plan .ft-grid{gap:clamp(22px,2.2vw,48px);margin-bottom:0}
footer.plan .ft-grid h3{margin-bottom:10px}
footer.plan .ft-col a{padding:3px 0}
footer.plan .ft-legal{padding:14px 0}
footer.plan .strapline{margin-bottom:8px}
footer.plan p{margin-bottom:8px}
.ft-news form{margin-top:10px}

/* THE RAILS. Three facts a donor's adviser checks, on the same column grid as the links above.
   As a flex row they took three unrelated widths (180px, 673px, then Legal flung to the right
   with a hole in front of it), which is what made the bottom of the footer look unresolved.
   The rule above them is the footer's SECOND and last: the hairline that used to sit 44px
   higher has gone, and that 44px of empty blue between two lines was exactly what Matthew was
   asking about. brand.css sets footer.plan .wrap{display:block}, hence the specificity step. */
footer.plan .ft-rails-in{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(20px,2.4vw,48px);margin-top:22px;padding-top:20px;
  border-top:1px solid rgba(255,255,255,.28)}
.rail{min-width:0}
.rail-h{display:block;font-family:'Poppins',Arial,sans-serif;font-weight:700;font-size:15px;color:#fff;margin-bottom:4px}
.rail span:not(.rail-h){font-size:14.5px;line-height:1.55;color:rgba(255,255,255,.94)}
@media(max-width:860px){ footer.plan .ft-rails-in{grid-template-columns:1fr;gap:18px} }
/* Between 860 and 1180 the five columns add up to more than the room available, so the grid
   squeezes every one of them below its stated minimum and the newsletter field goes tight
   again. Three columns there, and the form gets its own full-width row. */
@media(min-width:861px) and (max-width:1180px){
  footer.plan .ft-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  footer.plan .ft-grid .ft-news{grid-column:1 / -1}
  footer.plan .ft-grid .nl-pill{max-width:460px}
}


/* No row placement any more. The wrap is a plain block again: the footer is one row of five
   peer columns, so there is nothing left to place by hand. Every rule that used to force
   .ft-grid and .ft-bottom onto row 3 has gone with the two-column structure it propped up. */
