/* ==========================================================================
   IRETI polish layer
   Loads last. Three jobs:
     1. Browser surfaces — selection, caret, scrollbars, focus, underlines.
        The parts nobody draws still carry the design.
     2. Press and pointer truth — :active feedback, hover gated to real
        pointers so tapping on touch does not leave a stuck hover state.
     3. Responsive floor — legible and lively down to a 240px viewport
        (a folded cover screen in split view), not merely un-broken.
   ========================================================================== */

:root {
  --pl-navy: #0b2e6e;
  --pl-gold: #a97a08;
  --pl-ink: #14203a;
  --pl-soft: #5a6478;
  --pl-press: cubic-bezier(0.23, 1, 0.32, 1);
}

/* ==========================================================================
   1. Browser surfaces
   ========================================================================== */
::selection { background: #0b2e6e; color: #fff; text-shadow: none; }
::-moz-selection { background: #0b2e6e; color: #fff; text-shadow: none; }

/* selection on navy grounds inverts so it stays legible */
.px-band ::selection,
.mission ::selection,
.hero ::selection,
.pagehero ::selection,
.fund-meter ::selection,
.head .nav ::selection { background: #e8c565; color: #10203f; }

html { caret-color: #0b2e6e; scrollbar-color: #c3cddd transparent; scrollbar-width: thin; }
input, textarea, select { caret-color: #0b2e6e; }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: #c3cddd;
  border-radius: 999px;
  border: 3px solid #fff;
}
::-webkit-scrollbar-thumb:hover { background: #a9b6cc; }

/* one focus ring for the whole site, never the browser default */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid #0b2e6e;
  outline-offset: 2px;
  border-radius: 4px;
}
.px-band :focus-visible,
.mission :focus-visible,
.hero :focus-visible,
.fund-meter :focus-visible { outline-color: #f0cf7a; }

a { text-underline-offset: 0.18em; text-decoration-thickness: from-font; }

/* digits that sit in columns or count up should not jitter */
.impact-strip b,
.programme-proof .stats b,
.ip-raised, .ip-goal, .ip-foot, .ip-legend,
.dg-badge b,
.px-stats b { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

img { -webkit-user-drag: none; }

/* ==========================================================================
   2. Press feedback, and hover only where a real pointer exists
   ========================================================================== */
.btn, .donate, .outline-btn, .blue-btn, .dg-btn, .px-actions a,
.nav-cta, .wg-btn, .hamb, .nav-close, .arrow, .primary,
button[type="submit"], .fields button, .menu-toggle {
  transition: transform 160ms var(--pl-press), box-shadow 200ms var(--pl-press),
              background-color 200ms ease, color 200ms ease, border-color 200ms ease;
}
.btn:active, .donate:active, .outline-btn:active, .blue-btn:active,
.dg-btn:active, .px-actions a:active, .nav-cta:active, .wg-btn:active,
button[type="submit"]:active, .fields button:active {
  transform: scale(0.97);
}
.hamb:active, .nav-close:active, .menu-toggle:active { transform: scale(0.92); }
.wg-dots button:active { transform: scale(0.86); }

/* Touch taps fire :hover and it sticks until the next tap elsewhere. Undo the
   lift-and-zoom set on coarse pointers; the resting shadow stays. */
@media (hover: none), (pointer: coarse) {
  .campaign-large:hover, .catalogue-grid .campaign-large:hover, .campaign:hover,
  .prog .card:hover, .impact-stories article:hover, .action-panels article:hover,
  .board-grid .card:hover, .bn-card:hover, .wg-item:hover, .dg-pillar:hover,
  .tile:hover, .value-grid article:hover, .programme-pillars article:hover,
  .about-chapters article:hover, .contact-card:hover, .quick article:hover,
  .programme-proof .stats > div:hover, .impact-strip > div:hover,
  .event-photos > img:hover, .event-stack > img:hover {
    transform: none !important;
  }
  .campaign-large:hover > img, .prog .card:hover img,
  .impact-stories article:hover img, .board-grid .card:hover img,
  .wg-item:hover img, .bn-card:hover img, .dg-frame:hover img {
    transform: none !important;
  }
  .dg-pillar:hover::before, .programme-proof .stats > div:hover::before { transform: scaleX(0); }
}

/* card lift was slower than a press should read; tighten to UI speed */
.campaign-large, .catalogue-grid .campaign-large, .campaign, .prog .card,
.impact-stories article, .action-panels article, .board-grid .card,
.bn-card, .wg-item, .dg-pillar, .programme-proof .stats > div {
  transition: transform 220ms var(--pl-press), box-shadow 260ms var(--pl-press), border-color 220ms ease;
}

/* ==========================================================================
   3. Responsive floor — down to 240px
   Long single words are what actually break narrow layouts, so headings and
   labels are allowed to break before a container is allowed to overflow.
   ========================================================================== */
h1, h2, h3, h4, .dg-copy h2, .wg-head h2, .bn-head h2,
.recent-event h2, .px-band h2, label, .fields label, .ip-raised {
  overflow-wrap: break-word;
}

@media (max-width: 560px) {
  .fields { grid-template-columns: 1fr !important; }
  .fields .full { grid-column: auto !important; }
  .form-contact-row { grid-template-columns: 1fr !important; }
  .two-column, .split, .feature { grid-template-columns: 1fr !important; }
}

@media (max-width: 430px) {
  .wrap { padding: 54px 18px !important; }
  .form { padding: 22px 16px !important; }
  .pagehero { padding: 34px 18px !important; height: auto !important; min-height: 260px; }
  .recent-event, .beneficiaries, .work-gallery, .dignity.dg,
  .programme-proof, .programme-detail { padding-inline: 18px !important; }
  .impact-strip { grid-template-columns: 1fr 1fr !important; }
  .wg-item { width: clamp(180px, 62vw, 240px); }
  .bn-card { padding: 22px 16px; }
}

/* fold cover screen */
@media (max-width: 340px) {
  html { -webkit-text-size-adjust: 100%; }
  .wrap { padding: 44px 14px !important; }
  .form { padding: 18px 13px !important; }
  .fields { gap: 12px !important; }
  .pagehero { padding: 28px 14px !important; min-height: 220px; }
  .pagehero h1 { font-size: clamp(24px, 8.6vw, 32px) !important; letter-spacing: -.02em !important; }
  .pagehero p { font-size: 13.5px; }

  .recent-event, .beneficiaries, .work-gallery, .dignity.dg,
  .programme-proof, .programme-detail, .related-campaign, .mission,
  .px-band, .impact-strip, .action-panels {
    padding-inline: 14px !important;
  }

  .heroin h1, .hero h1 { font-size: clamp(26px, 9.4vw, 36px) !important; }
  .heroin p, .hero p { font-size: 14px !important; line-height: 1.55 !important; }
  .dg-copy h2, .recent-event h2, .wg-head h2, .bn-head h2, .px-band h2,
  .dignity.dg h2 { font-size: clamp(23px, 8.2vw, 30px) !important; max-width: none !important; }
  .mission h2 { font-size: clamp(22px, 7.8vw, 29px) !important; }

  .impact-strip { grid-template-columns: 1fr 1fr !important; gap: 8px !important; }
  .impact-strip > div { padding: 14px 8px !important; }
  .impact-strip b { font-size: 25px !important; }
  .impact-strip span { font-size: 11px !important; }

  .dg-pillars { gap: 10px !important; }
  .dg-pillar { padding: 16px 14px !important; }
  .dg-badge { padding: 12px 14px; left: -6px; bottom: -12px; }
  .dg-badge b { font-size: 29px; }

  .wg-item { width: clamp(158px, 70vw, 210px); }
  .wg-controls, .bn-controls { gap: 12px; }
  .fund-meter { padding: 34px 14px !important; }

  .action-panels { gap: 12px !important; }
  .action-panels article { padding: 22px 16px !important; }

  .event-meta span { font-size: 11.5px; padding: 6px 10px; }
  .upload-field input[type="file"] { font-size: 12px; }
  .upload-field input[type="file"]::file-selector-button { padding: 8px 11px; font-size: 11px; margin-right: 8px; }

  footer.site-footer { padding-inline: 14px !important; }
  .footer-bottom { font-size: 11.5px !important; }
}

/* half a folded cover screen — the narrowest thing that can realistically
   render this site. Everything must still read, and nothing may clip. */
@media (max-width: 288px) {
  .wrap { padding: 36px 11px !important; }
  .form { padding: 15px 11px !important; }
  .pagehero { padding: 24px 11px !important; min-height: 190px; }
  .pagehero h1 { font-size: clamp(20px, 9vw, 25px) !important; line-height: 1.14 !important; }

  .recent-event, .beneficiaries, .work-gallery, .dignity.dg, .programme-proof,
  .programme-detail, .related-campaign, .mission, .px-band, .impact-strip,
  .action-panels, footer.site-footer { padding-inline: 11px !important; }

  .heroin h1, .hero h1 { font-size: clamp(21px, 9.6vw, 27px) !important; }
  .dg-copy h2, .recent-event h2, .wg-head h2, .bn-head h2, .px-band h2,
  .dignity.dg h2, .mission h2 { font-size: clamp(19px, 8.4vw, 24px) !important; }
  body, .dg-lead, .wg-head p, .bn-head p { font-size: 14px; }

  /* two-up tiles stop earning their width here */
  .impact-strip { grid-template-columns: 1fr !important; }
  .impact-strip > div { padding: 12px 10px !important; display: flex; align-items: baseline; gap: 9px; justify-content: center; }
  .impact-strip b { font-size: 22px !important; }
  .programme-proof .stats { grid-template-columns: 1fr !important; }

  .dg-pillars { grid-template-columns: 1fr !important; }
  .dg-badge { position: static; margin-top: 12px; animation: none; justify-content: center; }
  .dg-actions .dg-btn { flex: 1 1 100%; padding: 13px 18px; font-size: 12px; }

  .wg-item { width: clamp(140px, 76vw, 178px); }
  .wg-btn { width: 38px; height: 38px; }
  .wg-dots button { width: 6px; height: 6px; }
  .wg-dots button[aria-current="true"] { width: 16px; }

  .event-meta { gap: 7px; }
  .event-meta span { font-size: 11px; padding: 5px 9px; }

  .ip-raised { font-size: 21px !important; }
  .ip-meter--feature .ip-raised { font-size: 27px !important; }
  .ip-foot { font-size: 12px !important; }

  .px-actions a, .btn, .donate, .outline-btn, .blue-btn { padding: 12px 18px; font-size: 11.5px; }
  .footer-bottom { font-size: 11px !important; }

  /* the drawer needs the width back at this size */
  .head .nav, .head .nav.mobileopen { width: 94vw !important; max-width: 94vw !important; }
  .nav-head img { width: 96px; }
}

/* keep touch targets honest no matter how narrow the screen gets */
@media (pointer: coarse) {
  .nav .drop a, .head .nav > a, .head .nav > div > a { min-height: 44px; display: flex; align-items: center; }
  .wg-dots button, .bn-controls .wg-dots button { position: relative; }
  .wg-dots button::after { content: ""; position: absolute; inset: -12px; }
}

@media (prefers-reduced-motion: reduce) {
  .btn, .donate, .outline-btn, .blue-btn, .dg-btn, .px-actions a, .nav-cta,
  .wg-btn, .hamb, .nav-close, .menu-toggle { transition: none !important; }
  .btn:active, .donate:active, .outline-btn:active, .blue-btn:active,
  .dg-btn:active, .px-actions a:active, .nav-cta:active, .wg-btn:active,
  .hamb:active, .nav-close:active, .menu-toggle:active { transform: none !important; }
}

/* ==========================================================================
   4. Icon system
   Replaces the ☎ ✉ ⌖ ☰ ▾ × glyphs that were standing in for icons. One
   stroke weight, one join style, sized to the text they sit beside.
   ========================================================================== */
.ico {
  width: 1em; height: 1em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.14em;
}
.top .topline { display: inline-flex; align-items: center; gap: 7px; }
.top .ico { width: 14px; height: 14px; opacity: .85; }
.hamb .ico { width: 20px; height: 20px; stroke-width: 1.9; }
.nav-close .ico { width: 17px; height: 17px; stroke-width: 2; }
.menu-toggle .ico { width: 13px; height: 13px; stroke-width: 2.1; }
.nav .drop .ico { display: none; }

/* ==========================================================================
   5. Narrow-viewport corrections
   Each of these fixes a rule that outranked the generic responsive tiers:
     .form-page .form{padding:28px!important}          — 2 classes, needed matching reach
     .form-contact-row article{padding-left:86px!important} — a gutter for an absolute icon
     .action-panels{margin:-18px auto 58px!important}  — side margin on a full-width grid
   ========================================================================== */
@media (max-width: 560px) {
  /* the icon leaves its reserved column and sits above the text instead */
  .form-page .form-contact-row article,
  .form-contact-row article {
    padding: 22px 18px 20px !important;
    min-width: 0;
  }
  .form-contact-row article > svg,
  .form-contact-row article > span,
  .form-contact-row article > i {
    position: static !important;
    display: block;
    margin: 0 0 12px !important;
    inset: auto !important;
  }
  .form-contact-row article b { padding-top: 0 !important; }
  .form-contact-row article p { overflow-wrap: anywhere; }
}

@media (max-width: 430px) {
  .form-page .form, .form-page .form.form { padding: 22px 16px !important; }
  .action-panels { margin-inline: 0 !important; width: auto !important; border-radius: 14px !important; }
}

@media (max-width: 340px) {
  .form-page .form, .form-page .form.form { padding: 18px 13px !important; }
  .action-panels { margin: -12px 0 44px !important; }
  .action-panels article { padding: 20px 15px !important; }
  .action-panels span { width: 46px !important; height: 46px !important; }
  /* long campaign titles were clipping inside the line-clamped box */
  .catalogue-grid .campaign-large h3,
  .campaign-large h3, .campaign h3 { overflow-wrap: anywhere; hyphens: auto; }
  .nav-foot { padding: 16px 14px !important; }
  .nav-foot .nav-meta { font-size: 11.5px; overflow-wrap: anywhere; }
}

@media (max-width: 288px) {
  .form-page .form, .form-page .form.form { padding: 15px 11px !important; }
  .form-contact-row { padding-inline: 11px !important; }
  .action-panels { margin: -8px 0 38px !important; }
}

/* ==========================================================================
   6. Impact strip — retire the alternating gold for good
   art.css carries `.impact-strip div:nth-child(2n){background:linear-gradient(...)!important}`
   at (0,2,1). An earlier override used `.impact-strip > div` at (0,1,1), so it
   lost on specificity despite also being !important and the gold survived at
   every width. Matching the offending selector is what actually settles it.
   The alternation encoded nothing — the four figures are peers.
   ========================================================================== */
.impact-strip div:nth-child(2n),
.impact-strip > div {
  background: #fff !important;
  background-image: none !important;
  color: var(--pl-ink) !important;
  border: 1px solid #e8edf5;
  box-shadow: 0 8px 22px -16px rgb(8 36 91 / .3);
}
.impact-strip div:nth-child(2n) b,
.impact-strip > div b { color: var(--pl-navy) !important; }
.impact-strip div:nth-child(2n) span,
.impact-strip > div span { color: var(--pl-soft) !important; }

/* the touch hit-area for the gallery dots used a negative inset, which shows up
   as scrollable overflow. Pad the control instead and draw the dot inside it. */
@media (pointer: coarse) {
  .wg-dots button::after { content: none; }
  .wg-dots button {
    width: 30px !important; height: 30px !important;
    padding: 0; background: transparent !important;
    display: grid; place-items: center;
  }
  .wg-dots button::before {
    content: ""; width: 7px; height: 7px; border-radius: 50%;
    background: #cbd5e4; transition: background .3s, width .3s var(--pl-press);
  }
  .wg-dots button[aria-current="true"]::before { background: #a97a08; width: 20px; border-radius: 4px; }
}

/* ==========================================================================
   7. Detector follow-ups
   Card accent stripes and the alert rule are replaced; the two remaining
   flags are deliberate and named below rather than silently left.
   ========================================================================== */

/* .success was a 3px navy bar on an alert — the exact card-accent tell.
   A tinted field with a hairline reads as a state without the costume. */
.success {
  border-left: 0 !important;
  border: 1px solid #c3d5f0 !important;
  background: #eef4fd !important;
  border-radius: 10px;
  padding: 13px 15px !important;
}

/* the pillar and stat tiles announced hover with a 3px stripe across the top.
   The icon tile warming and the card lifting already say it. */
.dg-pillar::before,
.programme-proof .stats > div::before { content: none !important; }
.dg-pillar:hover .dg-ico { background: linear-gradient(160deg, #fbe9bf, #efd694) !important; }
@media (hover: hover) and (pointer: fine) {
  .dg-pillar:hover, .programme-proof .stats > div:hover { border-color: #b9c9e2; }
}

/* the gallery dot grew by animating width; scale the drawn dot instead */
@media (pointer: coarse) {
  .wg-dots button::before {
    width: 7px !important;
    transition: background .3s ease, transform .3s var(--pl-press) !important;
    transform-origin: center;
  }
  .wg-dots button[aria-current="true"]::before {
    width: 7px !important; border-radius: 999px !important;
    transform: scaleX(2.6);
  }
}

/* Deliberate exceptions, kept knowingly:
   • .dg-quote's gold left rule — a blockquote rule is typographic convention,
     not a card accent; it is the anchor of that section's composition.
   • .ip-fill / .ip-deployed `transition: width` — a progress meter that grows
     by transform would distort the deployed segment nested inside it. It runs
     once, on scroll, on two elements.
   • .wg-track autoplay ("marquee") — the scrolling gallery is a requested
     feature, pauses on hover, focus and hidden tab, and is off under
     prefers-reduced-motion.
   • repeating-gradient hatch — the £0 progress track and the awaiting-photo
     slot use it to read as "waiting", which is the whole point of that state. */

/* ==========================================================================
   8. Desktop nav dropdown — floating card
   Three things were wrong with the incumbent:
     • audit.css sets `.nav>div{display:contents}`, which removes the box the
       panel anchors to, so `position:absolute` resolved against the wrong
       ancestor and `top` was forced to `auto`.
     • `display:none → block` cannot animate, so the panel popped.
     • A bare gap sat between trigger and panel; crossing it dropped :hover and
       the menu vanished mid-reach.
   The panel now stays in the DOM and is hidden by state, the gap is bridged,
   and experience.js holds it open for a grace period after the pointer leaves.
   ========================================================================== */
@media (min-width: 901px) {

  /* give the trigger group its box back — but never the drawer's own chrome,
     which is display:none on desktop and must stay that way */
  .head .nav > div:not(.nav-head):not(.nav-foot) {
    display: inline-flex !important;
    align-items: center;
    gap: 3px;
    position: relative !important;
  }
  .head .nav > .nav-head,
  .head .nav > .nav-foot { display: none !important; }
  .head .nav > div > a { white-space: nowrap; }

  .head .nav .menu-toggle {
    display: inline-grid !important;
    place-items: center;
    width: 20px; height: 20px;
    padding: 0 !important;
    border: 0; background: none;
    color: currentColor;
    opacity: .55;
    transition: transform 200ms var(--pl-press), opacity 160ms ease;
  }
  .head .nav .menu-toggle .ico { width: 11px; height: 11px; stroke-width: 2.4; }
  .head .nav > div:hover .menu-toggle,
  .head .nav > div.menu-open .menu-toggle { opacity: 1; }
  .head .nav > div.menu-open .menu-toggle { transform: rotate(180deg); }
  .head .nav > div:hover > a,
  .head .nav > div.menu-open > a { color: var(--pl-gold); }

  /* ---- the card ---- */
  .head .nav .drop {
    display: grid !important;
    grid-template-columns: 1fr;
    gap: 1px;
    position: absolute !important;
    top: calc(100% + 12px) !important;
    left: -12px !important;
    right: auto !important;
    width: max-content !important;
    min-width: 250px;
    max-width: 340px;
    padding: 7px !important;
    background: #fff;
    border: 1px solid rgb(11 46 110 / .09) !important;
    border-radius: 16px !important;
    box-shadow:
      0 1px 2px rgb(11 46 110 / .07),
      0 14px 30px -14px rgb(11 46 110 / .26),
      0 36px 64px -34px rgb(11 46 110 / .34) !important;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-7px) scale(.975);
    transform-origin: top left;
    transition:
      opacity 180ms var(--pl-press),
      transform 180ms var(--pl-press),
      visibility 0s linear 180ms;
    z-index: 40;
  }

  /* the reach-gap. Without this the pointer crosses dead space and the
     panel closes while the user is still moving toward it. */
  .head .nav .drop::before {
    content: "";
    position: absolute;
    left: 0; right: 0; top: -16px;
    height: 16px;
  }

  .head .nav > div:hover > .drop,
  .head .nav > div.menu-open > .drop,
  .head .nav > div:focus-within > .drop {
    opacity: 1;
    visibility: visible;
    transform: translateY(0) scale(1);
    transition:
      opacity 180ms var(--pl-press),
      transform 180ms var(--pl-press),
      visibility 0s;
  }

  /* six programmes earn a second column rather than a 6-deep list */
  .head .nav .drop:has(a:nth-child(6)) {
    grid-template-columns: 1fr 1fr;
    min-width: 428px;
    max-width: 470px;
    gap: 1px 4px;
  }

  /* ---- rows ---- */
  .head .nav .drop a {
    display: flex !important;
    align-items: center;
    gap: 9px;
    padding: 9px 11px !important;
    border-radius: 10px;
    font: 600 13.5px Karla, sans-serif !important;
    line-height: 1.35;
    color: #2b3852 !important;
    text-decoration: none;
    transition: background-color 140ms ease, color 140ms ease;
  }
  .head .nav .drop a::after {
    content: "";
    width: 5px; height: 5px;
    margin-left: auto;
    border-right: 1.6px solid currentColor;
    border-bottom: 1.6px solid currentColor;
    transform: rotate(-45deg) translateX(-2px);
    opacity: 0;
    transition: opacity 160ms ease, transform 200ms var(--pl-press);
  }
  .head .nav .drop a:hover,
  .head .nav .drop a:focus-visible {
    background: #f1f5fc;
    color: var(--pl-navy) !important;
  }
  .head .nav .drop a:hover::after,
  .head .nav .drop a:focus-visible::after {
    opacity: .5;
    transform: rotate(-45deg) translateX(0);
  }
  .head .nav .drop a:active { background: #e7eefa; }
}

@media (min-width: 901px) and (prefers-reduced-motion: reduce) {
  .head .nav .drop { transition: opacity 120ms linear, visibility 0s !important; transform: none !important; }
  .head .nav > div:hover > .drop,
  .head .nav > div.menu-open > .drop,
  .head .nav > div:focus-within > .drop { transform: none !important; }
  .head .nav .menu-toggle { transition: none !important; }
}

/* ==========================================================================
   9. Mobile navigation — full-screen
   Replaces the side drawer. A sheet that owns the whole viewport can afford
   real whitespace and real type, which is what makes a small screen feel
   calm rather than cramped. Materials over outlines: surfaces separate by
   tone and shadow, and the only rules left are hairlines at 6% navy.
   ========================================================================== */
@media (max-width: 900px) {

  .nav-scrim {
    background: rgb(9 18 38 / .28);
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
  }

  .head .nav,
  .head .nav.mobileopen {
    width: 100% !important;
    max-width: none !important;
    inset: 0 !important;
    border-radius: 0 !important;
    padding: 0 !important;
    background:
      radial-gradient(120% 70% at 100% 0%, rgb(232 199 106 / .10), transparent 62%),
      radial-gradient(110% 60% at 0% 100%, rgb(49 109 219 / .07), transparent 60%),
      #fdfdfe !important;
    box-shadow: none !important;
    transform: translate3d(0, 0, 0) !important;
    opacity: 0;
    visibility: hidden;
    transition:
      opacity 320ms cubic-bezier(0.32, 0.72, 0, 1),
      visibility 0s linear 320ms !important;
  }
  html.nav-open .head .nav,
  .head .nav.mobileopen {
    opacity: 1;
    visibility: visible;
    transition:
      opacity 380ms cubic-bezier(0.32, 0.72, 0, 1),
      visibility 0s !important;
  }

  /* ---- header row ---- */
  .head .nav > .nav-head {
    padding: 18px 22px 22px !important;
    border-bottom: 1px solid rgb(11 46 110 / .06) !important;
    background: transparent !important;
  }
  .nav-head img { width: 108px; }
  .nav-close {
    width: 42px !important; height: 42px !important;
    border: 0 !important;
    border-radius: 14px !important;
    background: rgb(11 46 110 / .05) !important;
    color: var(--pl-navy) !important;
  }
  .nav-close:hover { background: rgb(11 46 110 / .09) !important; transform: none; }

  /* ---- the list: big type, air, no boxes ---- */
  .head .nav > a,
  .head .nav > div {
    padding: 0 22px !important;
    border-bottom: 1px solid rgb(11 46 110 / .055) !important;
  }
  .head .nav > a,
  .head .nav > div > a {
    padding: 19px 0 !important;
    font: 600 clamp(19px, 5.6vw, 24px)/1.2 "Bricolage Grotesque", Karla, sans-serif !important;
    letter-spacing: -.02em;
    color: var(--pl-ink) !important;
  }
  .head .nav .menu-toggle {
    width: 36px !important; height: 36px !important;
    border: 0 !important;
    border-radius: 12px !important;
    background: rgb(11 46 110 / .05) !important;
    color: var(--pl-navy) !important;
  }
  .head .nav .menu-toggle .ico { width: 12px; height: 12px; }

  .head .nav .drop a {
    padding: 12px 0 12px 16px !important;
    font: 500 15px Karla, sans-serif !important;
    color: var(--pl-soft) !important;
    border-left: 1px solid rgb(11 46 110 / .08) !important;
  }
  .head .nav .drop a:hover,
  .head .nav .drop a:active { color: var(--pl-navy) !important; border-left-color: rgb(169 122 8 / .55) !important; }

  /* ---- footer: one sleek action, then quiet detail ---- */
  .head .nav > .nav-foot {
    padding: 22px !important;
    background: transparent !important;
    border-top: 1px solid rgb(11 46 110 / .06);
    gap: 18px !important;
  }
  .nav-foot .nav-cta {
    padding: 17px 22px !important;
    border-radius: 16px !important;
    font-size: 13px !important;
    letter-spacing: .06em;
    background: linear-gradient(180deg, #123c88, #0b2e6e) !important;
    color: #fff !important;
    box-shadow:
      0 1px 1px rgb(255 255 255 / .18) inset,
      0 10px 22px -10px rgb(11 46 110 / .55) !important;
  }
  .nav-foot .nav-meta { font-size: 13px !important; line-height: 1.9; color: var(--pl-soft) !important; }

  /* ---- staggered entrance ---- */
  html.nav-open .head .nav > .nav-head,
  html.nav-open .head .nav > a,
  html.nav-open .head .nav > div,
  html.nav-open .head .nav > .nav-foot {
    animation: nav-rise 460ms cubic-bezier(0.23, 1, 0.32, 1) both;
    animation-delay: calc(var(--i, 0) * 42ms + 60ms);
  }
}

@keyframes nav-rise {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: none; }
}

@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
  .head .nav, .head .nav.mobileopen { transition: opacity 140ms linear, visibility 0s !important; }
  html.nav-open .head .nav > * { animation: none !important; }
}

/* ==========================================================================
   10. Apple-leaning restraint pass
   Outlines were doing work that tone and shadow do better. Every hard grey
   rule becomes a low-alpha navy hairline so borders read as edges of a
   material rather than drawn lines.
   ========================================================================== */
.wg-btn, .bn-controls .wg-btn { border-color: rgb(11 46 110 / .10) !important; }
.bn-card, .dg-pillar, .programme-proof .stats > div,
.impact-strip > div, .impact-strip div:nth-child(2n) { border-color: rgb(11 46 110 / .07) !important; }
.fields input, .fields select, .fields textarea {
  border-color: rgb(11 46 110 / .14) !important;
  border-radius: 11px;
  transition: border-color 180ms ease, box-shadow 180ms ease, background-color 180ms ease;
}
.fields input:hover, .fields select:hover, .fields textarea:hover { border-color: rgb(11 46 110 / .24) !important; }
.fields input:focus, .fields select:focus, .fields textarea:focus {
  border-color: rgb(11 46 110 / .5) !important;
  box-shadow: 0 0 0 4px rgb(11 46 110 / .08);
  outline: none;
}
.upload-field input[type="file"] { border-color: rgb(11 46 110 / .16) !important; }
.event-meta span { background: rgb(11 46 110 / .05); color: var(--pl-navy); }

/* gold is an accent, not a second primary — keep it off large fills */
.ip-pct { background: rgb(169 122 8 / .10) !important; }

/* ==========================================================================
   11. Heading text reveal
   Words rise into place in sequence. Line wrappers clip so each word emerges
   from behind its own line rather than floating up over the paragraph above.
   ========================================================================== */
.tr .wl { display: inline-block; overflow: hidden; vertical-align: bottom; padding-bottom: 0.06em; }
.tr .w {
  display: inline-block;
  transform: translate3d(0, 106%, 0);
  opacity: 0;
  transition:
    transform 760ms cubic-bezier(0.23, 1, 0.32, 1),
    opacity 520ms cubic-bezier(0.23, 1, 0.32, 1);
  transition-delay: calc(var(--wi, 0) * 52ms);
  will-change: transform;
}
.tr.tr-in .w { transform: none; opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .tr .w { transform: none !important; opacity: 1 !important; transition: none !important; }
  .tr .wl { overflow: visible; }
}

/* ---- drawer corrections ----
   `.head .nav > div > a` also matches the Donate action inside .nav-foot, so
   the big-type rule was painting it ink-on-navy. And the row padding shorthand
   was wiping the horizontal padding set a rule earlier. */
@media (max-width: 900px) {
  .head .nav > a { padding: 19px 22px !important; }
  .head .nav > div:not(.nav-foot):not(.nav-head) > a { padding: 19px 0 !important; }

  .head .nav > .nav-foot > a.nav-cta,
  .head .nav .nav-foot .nav-cta {
    padding: 17px 22px !important;
    font: 700 13px Karla, sans-serif !important;
    letter-spacing: .06em !important;
    text-transform: uppercase;
    color: #fff !important;
    text-align: center;
    justify-content: center;
  }
  .head .nav > .nav-foot { border-bottom: 0 !important; }
  .head .nav > .nav-head { padding: 18px 22px 22px !important; }
}

/* the nav got a little wider with the trigger groups, which wrapped the CTA */
.head .navdonate, .head .donate { white-space: nowrap; }

/* Cap the word cascade. A nine-word heading should not have its last word
   arrive half a second after its first — the reveal is a flourish, not a wait. */
.tr .w { transition-delay: calc(min(var(--wi, 0), 7) * 52ms); }

/* ==========================================================================
   12. Our Recent Event — photo block proportion
   The lead frame carried `min-height:470px`, which made the photo column
   taller than the copy beside it (490 vs 415). With `align-items:center` the
   photos then overhung the text top and bottom, which reads as misalignment
   even though the two columns were the same height as each other.

   The block now stretches to the row instead of dictating it, so the photos
   end exactly where the copy ends and the lead is sized by the layout rather
   than by a fixed number.
   ========================================================================== */
@media (min-width: 900px) {
  .recent-event-inner { align-items: stretch !important; }

  /* the copy stays optically centred within its stretched column */
  .recent-event-inner > div:first-child {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  .event-photos {
    height: 100%;
    /* a floor so the block never collapses if the copy is short, and a
       ceiling so a long paragraph cannot stretch the photos to a wall */
    min-height: clamp(340px, 30vw, 420px);
    max-height: 520px;
    align-content: stretch;
  }
  .event-photos > .event-lead,
  .event-photos > .event-slot--lead {
    min-height: 0 !important;
    height: 100% !important;
  }
  .event-stack { height: 100%; }
  .event-stack > img { min-height: 0 !important; height: 100% !important; }
}

/* tablet: the two-up photo grid keeps a sane ratio on its own */
@media (min-width: 700px) and (max-width: 899px) {
  .event-photos { min-height: 0; }
  .event-photos > .event-lead { min-height: 0 !important; aspect-ratio: 4 / 5; height: auto !important; }
  .event-stack > img { min-height: 0 !important; }
}

/* stacked: the lead is a portrait source, so give it a portrait-leaning crop
   rather than a fixed pixel height that fights the viewport */
@media (max-width: 699px) {
  .event-photos > .event-lead {
    min-height: 0 !important;
    aspect-ratio: 4 / 5;
    height: auto !important;
    max-height: 62vh;
  }
  .event-stack { grid-template-columns: 1fr 1fr; grid-template-rows: auto; }
  .event-stack > img { min-height: 0 !important; aspect-ratio: 1 / 1; height: auto !important; }
}

/* the stack must fill the row at every width the two-up grid is active,
   or it ends short of the lead (63px at 820px before this) */
@media (min-width: 700px) {
  .event-photos { align-items: stretch; }
  .event-stack { height: 100%; grid-template-rows: 1fr 1fr; }
  .event-stack > img { height: 100% !important; min-height: 0 !important; aspect-ratio: auto !important; }
}

/* ==========================================================================
   13. Action panels — restore the mobile gutter
   The card group is meant to float: rounded, shadowed, inset from the page
   edge. An earlier `margin-inline:0` (added to stop an overflow at 240px)
   flattened it edge-to-edge at every width under 430, so the navy card bled
   into both screen edges. The overflow was caused by an explicit `width`
   fighting a margin, not by the margin itself — `width:auto` keeps the gutter
   and cannot overflow.
   ========================================================================== */
@media (max-width: 430px) {
  .action-panels {
    width: auto !important;
    margin: -14px 16px 44px !important;
    border-radius: 18px !important;
    overflow: hidden;
    box-shadow: 0 14px 34px -18px rgb(11 46 110 / .28) !important;
  }
  /* stacked cards separate along the axis they actually stack on */
  .action-panels article {
    border-right: 0 !important;
    border-bottom: 1px solid rgb(11 46 110 / .07) !important;
  }
  .action-panels article:last-child { border-bottom: 0 !important; }
}
@media (max-width: 340px) {
  .action-panels { margin: -10px 12px 38px !important; border-radius: 16px !important; }
}
@media (max-width: 288px) {
  .action-panels { margin: -8px 10px 32px !important; border-radius: 14px !important; }
}

/* ==========================================================================
   14. Event photo stack — let stretch do the work
   `.event-stack{height:100%}` looked like the fix and was the cause: a grid
   item only stretches to its row when its height is `auto`. Giving it 100%
   opted it out of stretch, and 100% of an indefinite-height parent resolves
   back to content height — so the stack sat 63px short of the lead.
   With height:auto it stretches to the row, its 1fr rows become definite,
   and the images fill them.
   ========================================================================== */
@media (min-width: 700px) {
  .event-photos { align-items: stretch !important; }
  .event-stack {
    height: auto !important;
    align-self: stretch !important;
    display: grid !important;
    grid-template-rows: 1fr 1fr !important;
    gap: 14px;
  }
  .event-stack > img {
    height: 100% !important;
    min-height: 0 !important;
    aspect-ratio: auto !important;
    object-fit: cover;
  }
}

/* ==========================================================================
   15. Header row at drawer widths
   `.head` is a grid with `space-between`. With the desktop nav taken out of
   flow (position:fixed) and the Donate button hidden, the hamburger was
   auto-placed into the second column and landed mid-header rather than at the
   right edge. A flex row states the intent directly.
   ========================================================================== */
@media (max-width: 900px) {
  .head {
    display: flex !important;
    align-items: center;
    justify-content: space-between !important;
    gap: 16px !important;
  }
  .head .brandmark { margin-right: auto; }
  .hamb { margin-left: auto !important; flex: none; }
}

/* ==========================================================================
   16. Drawer submenu toggle
   The control worked (36×36, rotating correctly) but read as a smudge: a
   12px chevron at 33% of a 5%-opacity tile, sitting beside 24px bold type.
   It also missed the 44px touch minimum. Sized up, given real contrast, and
   the open state now reads as a state rather than a slightly different grey.
   ========================================================================== */
@media (max-width: 900px) {
  .head .nav .menu-toggle {
    width: 44px !important;
    height: 44px !important;
    border-radius: 14px !important;
    background: rgb(11 46 110 / .07) !important;
    color: var(--pl-navy) !important;
    display: grid !important;
    place-items: center !important;
    justify-self: end;
    transition:
      transform 260ms cubic-bezier(0.23, 1, 0.32, 1),
      background-color 200ms ease,
      color 200ms ease !important;
  }
  .head .nav .menu-toggle .ico {
    width: 18px !important;
    height: 18px !important;
    stroke-width: 2.2 !important;
    opacity: 1;
  }
  .head .nav .menu-toggle:active { transform: scale(0.9); }

  /* open: the tile takes the brand tint so state is legible at a glance,
     not just inferred from which way a faint arrow points */
  .head .nav .menu-toggle[aria-expanded="true"] {
    transform: rotate(180deg);
    background: var(--pl-navy) !important;
    color: #fff !important;
  }
  .head .nav .menu-toggle[aria-expanded="true"]:active { transform: rotate(180deg) scale(0.9); }

  /* the row gives the control room without shifting the label */
  .head .nav > div:not(.nav-head):not(.nav-foot) {
    grid-template-columns: 1fr auto !important;
    align-items: center;
    column-gap: 12px;
  }
}

@media (max-width: 340px) {
  .head .nav .menu-toggle { width: 40px !important; height: 40px !important; border-radius: 12px !important; }
  .head .nav .menu-toggle .ico { width: 16px !important; height: 16px !important; }
}

@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
  .head .nav .menu-toggle,
  .head .nav .menu-toggle[aria-expanded="true"] { transition: background-color 140ms ease, color 140ms ease !important; }
}

/* ==========================================================================
   17. Docked header
   The bar stays at the top and content passes beneath it.

   art.css already had `.head{background:rgba(255,255,255,.92);backdrop-filter:
   blur(17px)}` — the header was translucent before this, the blur already sat
   on .head itself, and the mobile drawer (position:fixed inside it) has been
   working against that all along. So the filter stays where it is rather than
   being moved to a pseudo-element; .head::before keeps carrying the gold
   hairline it was already drawing.

   The decorative curve belongs to the top of the page, not to a docked bar
   hanging over moving content, so it retires on scroll and a hairline plus a
   soft shadow take over.
   ========================================================================== */
.head {
  position: sticky;
  top: 0;
  z-index: 90;
  background: rgb(255 255 255 / .70) !important;
  backdrop-filter: blur(18px) saturate(180%) !important;
  -webkit-backdrop-filter: blur(18px) saturate(180%) !important;
  transition: background-color 320ms ease, box-shadow 320ms ease;
}

.head::after { transition: opacity 300ms ease; }
.head .logo { transition: transform 320ms cubic-bezier(0.23, 1, 0.32, 1); transform-origin: left center; }

html[data-scrolled] .head {
  background: rgb(255 255 255 / .84) !important;
  box-shadow:
    0 1px 0 rgb(11 46 110 / .07),
    0 12px 30px -20px rgb(11 46 110 / .32);
}
html[data-scrolled] .head::after { opacity: 0; }
html[data-scrolled] .head .logo { transform: scale(.94); }

/* the thin contact bar scrolls away; only the nav docks */
.top { position: relative; z-index: 1; }

/* a docked bar needs its menu above everything that scrolls past */
@media (min-width: 901px) { .head .nav .drop { z-index: 60; } }

/* the drawer paints its own ground; two stacked blurs are wasteful and
   repaint badly on iOS Safari */
@media (max-width: 900px) {
  html.nav-open .head { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; background: transparent !important; }
}

@media (prefers-reduced-motion: reduce) {
  .head, .head::after, .head .logo { transition: none !important; }
}

/* ==========================================================================
   18. Drawer submenu — visibility and presence
   audit.css carries `.nav.mobileopen > div .drop{display:none!important}` at
   (0,3,1), which outranked the accordion's own `.head .nav .drop` at (0,3,0).
   The panel therefore only ever appeared while `.menu-open` was present — and
   hover-intent stripped that 220ms after a tap, which is the snap-back.
   Matching that specificity settles it; the JS now moves both flags together.
   ========================================================================== */
@media (max-width: 900px) {
  .head .nav.mobileopen > div > .drop,
  .head .nav > div > .drop {
    display: block !important;
    max-height: 0;
    overflow: hidden;
    transition: max-height 380ms cubic-bezier(0.32, 0.72, 0, 1),
                opacity 260ms ease,
                padding 300ms ease;
    opacity: 0;
    padding-block: 0 !important;
  }
  .head .nav.mobileopen > div.menu-open > .drop,
  .head .nav > div > .drop.is-open {
    max-height: 520px;
    opacity: 1;
    padding-block: 4px 14px !important;
  }

  /* the nested group reads as a recess, not as more list items */
  .head .nav > div > .drop {
    margin: 0 0 0 2px;
    border-left: 2px solid rgb(11 46 110 / .12) !important;
    background: linear-gradient(90deg, rgb(11 46 110 / .035), transparent 70%);
    border-radius: 0 10px 10px 0;
  }
  .head .nav .drop a {
    padding: 13px 12px 13px 18px !important;
    font: 600 15.5px Karla, sans-serif !important;
    color: #38455e !important;
    border-left: 0 !important;
    border-radius: 0 8px 8px 0;
    min-height: 46px;
    display: flex !important;
    align-items: center;
  }
  .head .nav .drop a:active { background: rgb(11 46 110 / .06); color: var(--pl-navy) !important; }

  /* breathing room between the chevron and the screen edge */
  .head .nav > a,
  .head .nav > div:not(.nav-head):not(.nav-foot) { padding-inline: 22px 18px !important; }
  .head .nav .menu-toggle { margin-right: 2px; }
}

@media (max-width: 380px) {
  .head .nav > a,
  .head .nav > div:not(.nav-head):not(.nav-foot) { padding-inline: 18px 14px !important; }
  .head .nav .drop a { font-size: 15px !important; padding-left: 16px !important; }
}

@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
  .head .nav > div > .drop { transition: opacity 140ms linear !important; }
}

/* ---- submenu opens on .menu-open, the flag nav.js owns ---- */
@media (max-width: 900px) {
  .head .nav.mobileopen > div.menu-open > .drop,
  .head .nav > div.menu-open > .drop {
    display: block !important;
    max-height: 560px;
    opacity: 1;
    padding-block: 4px 14px !important;
  }
  /* a little more air between the control and the screen edge */
  .head .nav > a,
  .head .nav > div:not(.nav-head):not(.nav-foot) { padding-inline: 22px !important; }
  .head .nav .menu-toggle { margin-right: 0; }
}
@media (max-width: 380px) {
  .head .nav > a,
  .head .nav > div:not(.nav-head):not(.nav-foot) { padding-inline: 18px !important; }
}

/* ---- drawer edge: the panel's own scrollbar was eating the gutter ----
   The drawer scrolls, and the themed 11px scrollbar sits inside it, so the
   chevron lost most of its breathing room to a strip of chrome. A nav sheet
   does not need a visible scrollbar; hiding it returns the gutter. */
@media (max-width: 900px) {
  .head .nav { scrollbar-width: none; -ms-overflow-style: none; }
  .head .nav::-webkit-scrollbar { width: 0; height: 0; display: none; }
  .head .nav > a,
  .head .nav > div:not(.nav-head):not(.nav-foot) { padding-inline: 22px 24px !important; }
  .head .nav > .nav-head { padding-inline: 22px 20px !important; }
}
@media (max-width: 380px) {
  .head .nav > a,
  .head .nav > div:not(.nav-head):not(.nav-foot) { padding-inline: 18px 20px !important; }
}

/* ==========================================================================
   19. Docked header legibility over dark content
   The homepage scrolls a 720px navy hero beneath the bar; every other page
   clears a 380px page hero onto white almost immediately. At 70% white the
   bar went murky over that hero and the navy nav text lost contrast, which
   reads as the header failing rather than as a translucency problem.

   Docked state is now opaque enough to guarantee legibility over anything,
   while still shifting tone with what passes beneath it. A hairline is always
   present once docked so the bar has a defined edge on any ground.
   ========================================================================== */
html[data-scrolled] .head {
  background: rgb(255 255 255 / .92) !important;
  border-bottom: 1px solid rgb(11 46 110 / .08);
  box-shadow: 0 10px 28px -22px rgb(11 46 110 / .34);
}

/* at rest the bar sits above the hero rather than over it, so it can stay
   lighter and let the page read through */
.head { background: rgb(255 255 255 / .78) !important; }

/* nav text keeps its weight against whatever is behind the material */
html[data-scrolled] .head .nav > a,
html[data-scrolled] .head .nav > div > a { color: #22305c; }

/* ==========================================================================
   20. Retire the header curve
   `.head::after` was a white curve hanging 26px BELOW the bar. Undocked and
   over white content it read as a soft page edge. Docked over the homepage's
   720px navy hero it became a visible white band beneath the nav — so the bar
   looked ~136px tall with the links sitting in its upper half. That is the
   "sticks at half" symptom, and it only showed on home because every other
   page clears its 380px hero onto white, where white-on-white hides it.

   Fading it on scroll made the fix depend on a scroll threshold. A docked bar
   wants a clean edge, so the curve goes entirely; the gold hairline on
   .head::before and the docked shadow carry the boundary.
   ========================================================================== */
.head::after { content: none !important; }
.head { overflow: visible; }

/* the boundary is now purely the hairline plus the docked shadow */
html[data-scrolled] .head {
  box-shadow:
    0 1px 0 rgb(11 46 110 / .10),
    0 14px 34px -24px rgb(11 46 110 / .38);
}

/* ==========================================================================
   21. Skip link
   First thing a keyboard reaches. It is a same-page jump, but the site is
   hash-routed, so the handler in site.js focuses <main> rather than letting
   the hash change and re-run the router.
   ========================================================================== */
.skip-link {
  position: absolute;
  left: 12px;
  top: -64px;
  z-index: 200;
  padding: 12px 18px;
  border-radius: 0 0 10px 10px;
  background: var(--navy, #0b2e6e);
  color: #fff;
  font: 600 14px/1 Karla, system-ui, sans-serif;
  text-decoration: none;
  transition: top 180ms cubic-bezier(.23, 1, .32, 1);
}
.skip-link:focus { top: 0; }
#content:focus { outline: none; }
#content:focus-visible { outline: 3px solid var(--sapphire, #174ca5); outline-offset: -3px; }

/* ==========================================================================
   22. Visually hidden heading
   Names a card grid that sits directly beneath the page h1, so the heading
   outline does not jump from h1 to h3. No visual change.
   ========================================================================== */
.sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  overflow: hidden !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* ==========================================================================
   23. Sideways drift between phone and tablet widths
   Below 800px one rule gives .action-panels `margin: 0 18px`, while the width
   it inherits is still 100%. An element that is 100% of its parent *and* has
   horizontal margins is wider than its parent by the sum of those margins, so
   the page gained exactly 18px of horizontal scroll — enough to feel like the
   site slides left and right on a phone. Narrower tiers already set width to
   auto, which is why 430px and below were unaffected.
   ========================================================================== */
@media (max-width: 800px) {
  .action-panels { width: auto !important; }
}

/* ==========================================================================
   24. Page heroes clipping their own subtitle
   .pagehero was given a fixed `height` — 380px, 310px below 800px — and only
   released to `height: auto` below 430px. Between those widths a heading that
   wraps to four lines pushes the subtitle past the fixed box, where the next
   section paints over it: the sentence simply stops mid-word. Measured at
   600px, every one of the twelve hero pages overflowed by 94px.
   A fixed height on a box whose content reflows is the bug. min-height keeps
   the intended proportions and lets tall content grow instead.
   Tiers are ordered narrowest-last so the small-screen sizes still win.
   ========================================================================== */
.pagehero { height: auto !important; min-height: 380px; }
@media (max-width: 800px) { .pagehero { min-height: 310px; } }
@media (max-width: 430px) { .pagehero { min-height: 260px; } }
@media (max-width: 340px) { .pagehero { min-height: 220px; } }
@media (max-width: 288px) { .pagehero { min-height: 190px; } }

/* ==========================================================================
   25. Hero proportions on phones and tablets
   The heading kept its desktop size of 43px all the way down, so on a 390px
   phone the title wrapped to four lines and the hero took 41% of the screen
   before a visitor saw any content. A page header should introduce the page,
   not occupy it.
   Each tier drops the heading, the subtitle and the box together — shrinking
   the height alone would only crowd the text. Ordered narrowest-last so the
   smallest sizes win.
   ========================================================================== */
@media (max-width: 900px) {
  .pagehero { min-height: 250px; padding: 34px 28px !important; }
  .pagehero h1 { font-size: clamp(28px, 4.4vw, 34px) !important; line-height: 1.16 !important; margin: 10px auto !important; }
  .pagehero p { font-size: 15px; }
  .pagehero .eyebrow { font-size: 11.5px; }
}

@media (max-width: 560px) {
  .pagehero { min-height: 215px; padding: 30px 20px !important; }
  .pagehero h1 { font-size: clamp(24px, 6.2vw, 30px) !important; }
  .pagehero p { font-size: 14.5px; }
}

@media (max-width: 430px) {
  .pagehero { min-height: 190px; padding: 26px 16px !important; }
  .pagehero h1 { font-size: clamp(22px, 6.6vw, 27px) !important; line-height: 1.15 !important; margin: 8px auto !important; }
  .pagehero p { font-size: 14px; }
  .pagehero .eyebrow { font-size: 11px; letter-spacing: .12em; }
}

@media (max-width: 340px) {
  .pagehero { min-height: 165px; padding: 22px 13px !important; }
  .pagehero h1 { font-size: clamp(19px, 6.8vw, 22px) !important; }
  .pagehero p { font-size: 13.5px; }
}

@media (max-width: 288px) {
  .pagehero { min-height: 148px; padding: 18px 11px !important; }
  .pagehero h1 { font-size: clamp(17px, 7vw, 19px) !important; }
  .pagehero p { font-size: 13px; }
}

/* ==========================================================================
   26. Form confirmation
   Shown when a submission succeeds. Errors stay inline beside the form,
   because those need to be read next to the field being corrected.
   ========================================================================== */
/* The hidden attribute hides an element through the browser's own stylesheet,
   which any author rule outranks — so `display: grid` below silently defeated
   `root.hidden = true` and the Close button appeared to do nothing. This rule
   is more specific than the one beneath it, so hiding wins. */
.confirm-scrim[hidden] { display: none; }
.confirm-scrim {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgb(6 20 48 / .55);
  backdrop-filter: blur(3px);
  animation: confirm-in 200ms cubic-bezier(.23, 1, .32, 1);
}
.confirm-card {
  width: min(100%, 430px);
  padding: 34px 30px 28px;
  border-radius: 20px;
  background: #fff;
  text-align: center;
  box-shadow: 0 26px 60px rgb(6 20 48 / .34);
  animation: confirm-rise 240ms cubic-bezier(.23, 1, .32, 1);
}
.confirm-tick {
  display: grid;
  place-items: center;
  width: 58px;
  height: 58px;
  margin: 0 auto 18px;
  border-radius: 50%;
  background: #e7f5ee;
  color: #0f6b46;
}
.confirm-tick svg { width: 27px; height: 27px; }
.confirm-card h2 {
  margin: 0 0 10px;
  color: var(--navy, #0b2e6e);
  font-size: 23px;
  line-height: 1.2;
}
.confirm-message {
  margin: 0;
  color: #4a5a71;
  font-size: 15px;
  line-height: 1.6;
}
/* The transfer reference is the one thing they must copy correctly. */
.confirm-reference {
  margin: 18px 0 0;
  padding: 13px 14px;
  border: 1px dashed #cbd6e7;
  border-radius: 11px;
  background: #f6f9fe;
  color: var(--navy, #0b2e6e);
  font: 600 16px/1.4 "IBM Plex Mono", ui-monospace, Menlo, monospace;
  letter-spacing: .02em;
  overflow-wrap: anywhere;
}
.confirm-close { margin-top: 22px; min-width: 132px; }

@keyframes confirm-in { from { opacity: 0 } }
@keyframes confirm-rise { from { opacity: 0; transform: translateY(12px) scale(.97) } }

@media (max-width: 430px) {
  .confirm-card { padding: 28px 22px 24px; border-radius: 17px; }
  .confirm-card h2 { font-size: 20px; }
  .confirm-message { font-size: 14px; }
  .confirm-tick { width: 50px; height: 50px; margin-bottom: 15px; }
}
@media (prefers-reduced-motion: reduce) {
  .confirm-scrim, .confirm-card { animation: none; }
}
