/* ==========================================================================
   True Kind Foundation — stylesheet
   White and cool-grey surfaces on the Tailwind gray neutral ramp, carrying the
   four logo colours — green, blue, purple, red — as the accent system.
   Every colour is a token in :root. Nothing below hardcodes one.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */
:root{
  /* ---- BRAND PALETTE -----------------------------------------------------
     THREE tiers, and the reason is measured, not stylistic. Against the light
     surfaces the pure logo colours give: green 2.48:1, blue 3.23:1, red 4.13:1,
     purple 5.61:1. Only purple clears AA. White text on them is worse still —
     green 2.67, blue 3.46, red 4.43 — so a vivid-filled button with white text
     is unreadable. Hence:
       --brand-*   exact logo colour. Fills, tints, rules, icons, graphics.
                   Never small text.
       --green/blue/purple/red   darkened to clear 4.5:1 as text on a surface.
       --*-btn     darkened to carry white text at 4.5:1.
       --tag-*     darker again, for text sitting ON a colour tint.
     -------------------------------------------------------------------- */
  --brand-green:  #59B306;
  --brand-blue:   #0392D4;
  --brand-purple: #7D4AB1;
  --brand-red:    #DF3548;
  /* Fifth accent. The logo only carries four colours but the site has five
     programmes, so the fifth is blended from the logo's blue and green rather
     than invented — it sits inside the mark's own range. */
  --brand-teal:   #0C9E8F;

  /* Text-safe (>=4.5:1 on paper, paper-2 and paper-3) */
  --green:       #3F7F04;
  --blue:        #0276AC;
  --purple:      #7D4AB1;
  --red:         #C92135;
  --teal:        #067A6E;

  /* Solid fills carrying white text (>=4.5:1 against #FFFFFF) */
  --green-btn:   #417F05;
  --blue-btn:    #0379B0;
  --purple-btn:  #7D4AB1;
  --teal-btn:    #05796D;
  --clay:        #CE2438;
  --clay-deep:   #A81B2B;

  /* Darker steps for hover */
  --blue-deep:   #015A85;
  --purple-deep: #5B3480;
  --green-deep:  #2F5D03;
  --teal-deep:   #044F48;
  --red-deep:    #A81B2B;

  /* ---- SINGLE SWITCH FOR THE PRIMARY ACTION -----------------------------
     The client keeps revisiting this one. Change these two values and every
     primary button on every page follows — nothing else needs touching.
     Green (--green-btn / --green-deep) is the wordmark colour if they'd
     rather lead with that than the red. */
  --action:      var(--clay);
  --action-hover:var(--clay-deep);

  /* ---- PROGRAMME TINTS --------------------------------------------------
     0.16 is the ceiling here: past it the uppercase tag sitting on the tint
     drops under 4.5:1 (red is the first to fail). Verified, do not raise. */
  --tint-blue:   rgba(3,146,212,0.16);
  --tint-purple: rgba(125,74,177,0.16);
  --tint-green:  rgba(89,179,6,0.16);
  --tint-red:    rgba(223,53,72,0.16);
  --tint-teal:   rgba(12,158,143,0.16);

  /* Tag colours — text ON the 0.16 tint. Solved so each clears 4.5:1 against
     its own tint over BOTH white and paper-2; the plain text tier above is too
     light here (blue would land at 4.17, green 4.26). */
  --tag-blue:   #026A9B;
  --tag-purple: #7A49AD;
  --tag-green:  #3A7404;
  --tag-red:    #BD1E30;
  --tag-teal:   #097167;

  /* All four logo colours as one rule — the brand signature */
  --brand-bar: linear-gradient(90deg,
                 var(--brand-blue) 0%, var(--brand-purple) 33%,
                 var(--brand-green) 66%, var(--brand-red) 100%);

  /* ---- NEUTRALS ---------------------------------------------------------
     The supplied neutrals (#1F2937 / #4B5563 / #E5E7EB) are the Tailwind gray
     ramp, so the steps the design needs but the brief did not list are taken
     from the same ramp rather than invented: gray-900 for dark surfaces,
     gray-800 for the second dark step. paper-3 is a third cool surface, since
     the section rhythm here alternates across three. */
  --ink:       #111827;   /* gray-900 — dark bands, 17.7:1 with white */
  --ink-2:     #1F2937;   /* gray-800 */
  --paper:     #FFFFFF;
  --paper-2:   #F5F7FA;   /* the supplied BACKGROUND */
  --paper-3:   #EAEEF3;

  /* Text */
  --text:      #1F2937;   /* 14.7:1 on white, 13.7:1 on paper-2 */
  --text-soft: #4B5563;   /* 7.6:1 / 7.0:1 */
  --text-mute: #5B6472;   /* eyebrows, labels, captions — these are small, so
                             they need AA on all THREE surfaces. gray-500
                             (#6B7280) only reaches 4.15:1 on paper-3, so this
                             is one step darker than the ramp would suggest. */

  /* ---- HAIRLINES --------------------------------------------------------
     Expressed as alpha of --ink rather than the flat #E5E7EB from the brief,
     because these same rules sit over white, over paper-2/3 AND over colour
     tints — a solid grey looks wrong on a tint. rgba(17,24,39,0.11) resolves to
     #E5E6E7 over white, i.e. the supplied BORDER value, and adapts elsewhere.
     Note #E5E7EB is only 1.24:1 against white, so it reads as a whisper; that
     is intended for dividers, and --rule-strong (~gray-300) does the
     structural work. */
  --rule:        rgba(17,24,39,0.11);
  --rule-strong: rgba(17,24,39,0.20);
  --rule-invert: rgba(255,255,255,0.16);
  --border-flat: #E5E7EB;   /* the literal supplied value, where a solid is wanted */

  /* ---- DARK BANDS -------------------------------------------------------
     The story / CTA / footer sections are deep purple-into-slate gradients.
     These were the last hardcoded colours in the file; tokenised so the whole
     palette really is editable from this one block. Derived from
     --brand-purple, ending on --ink so the dark bands share the neutral ramp
     rather than drifting warm. */
  --deep-1: #4A2E6B;
  --deep-2: #3A2355;
  --deep-3: #33204C;
  --deep-4: #2C1A42;
  --deep-5: #241A3D;

  /* Form feedback fills — alpha of the button tiers, so they track the palette */
  --tint-ok:  rgba(65,127,5,0.08);    /* --green-btn */
  --tint-err: rgba(206,36,56,0.07);   /* --clay */

  /* Type scale — wide contrast between display and body */
  --fs-display: clamp(2.6rem,  1.55rem + 4.1vw, 4.4rem);
  --fs-h1:      clamp(2.15rem, 1.55rem + 2.6vw, 3.35rem);
  --fs-h2:      clamp(1.75rem, 1.36rem + 1.7vw, 2.6rem);
  --fs-h3:      clamp(1.1rem,  1.04rem + 0.3vw, 1.3rem);
  --fs-lede:    clamp(1.06rem, 1rem + 0.3vw, 1.22rem);
  --fs-body:    1rem;
  --fs-sm:      0.925rem;
  --fs-xs:      0.82rem;
  --fs-mono:    0.68rem;
  --fs-label:   0.64rem;   /* uppercase mono labels — bumped on mobile */

  /* Spacing */
  --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 18px;
  --sp-5: 26px;  --sp-6: 36px;  --sp-7: 52px;  --sp-8: 72px;
  --sp-9: 96px;  --sp-10:128px;

  /* Section rhythm — deliberately generous */
  --section-y:   clamp(76px, 5vw + 44px, 136px);
  --section-y-s: clamp(56px, 3.5vw + 32px, 92px);

  /* Shape */
  /* Dial easing: fast out, long settle — the arc arrives rather than stops.
     This is ease-out-cubic expressed as a bezier, and it is deliberately the
     exact analytic equivalent of the 1-(1-t)^3 used by the count-up in main.js.
     Any other curve here and the digits would drift ahead of or behind the
     stroke; matched, they land on the same frame. */
  --ease-dial: cubic-bezier(0.33, 1, 0.68, 1);

  --radius:    14px;
  --radius-sm: 9px;
  --radius-lg: 20px;
  --radius-pill: 100px;

  /* Elevation — barely there. Depth comes from hairlines, not shadow. */
  --shadow-1: 0 1px 2px rgba(17,24,39,0.03);
  --shadow-2: 0 2px 4px rgba(17,24,39,0.04), 0 12px 28px -20px rgba(17,24,39,0.20);
  --shadow-3: 0 4px 10px rgba(17,24,39,0.05), 0 30px 60px -34px rgba(17,24,39,0.32);

  /* Layout */
  --maxw:        1180px;
  --maxw-narrow: 760px;
  --gutter: clamp(22px, 4vw, 40px);

  /* Motion */
  --ease: cubic-bezier(.22,.61,.24,1);
  --dur:  .3s;

  /* Fonts */
  --font-body:    'Work Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
}

/* --------------------------------------------------------------------------
   2. BASE
   -------------------------------------------------------------------------- */
*, *::before, *::after{ box-sizing:border-box; }

html{
  scroll-behavior:smooth;
  scroll-padding-top:88px;
  -webkit-text-size-adjust:100%;
}

body{
  margin:0;
  background:var(--paper);
  color:var(--text);
  font-family:var(--font-body);
  font-size:var(--fs-body);
  font-weight:400;
  line-height:1.72;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}
body.nav-open{ overflow:hidden; }

h1,h2,h3,h4{
  font-family:var(--font-display);
  color:var(--ink);
  margin:0;
  text-wrap:balance;
}
h1{
  font-size:var(--fs-h1); font-weight:400;
  line-height:1.08; letter-spacing:-0.028em;
}
h2{
  font-size:var(--fs-h2); font-weight:400;
  line-height:1.12; letter-spacing:-0.024em;
}
h3{
  font-size:var(--fs-h3); font-weight:500;
  line-height:1.34; letter-spacing:-0.012em;
}

p{ margin:0 0 1.1em; }
p:last-child{ margin-bottom:0; }

a{ color:inherit; }
img,svg{ max-width:100%; display:block; }
strong,b{ font-weight:600; }

::selection{ background:var(--ink); color:var(--paper); }

:focus-visible{
  outline:2px solid var(--ink);
  outline-offset:3px;
  border-radius:3px;
}

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
}

/* --------------------------------------------------------------------------
   3. LAYOUT PRIMITIVES
   -------------------------------------------------------------------------- */
.wrap{
  width:100%; max-width:var(--maxw);
  margin-inline:auto; padding-inline:var(--gutter);
}
.wrap-narrow{ max-width:var(--maxw-narrow); }

/* Grid items default to min-width:auto (= min-content), which lets a single
   long child push a column past the container. Opt every layout grid out. */
.story-grid > *, .contact-grid > *, .cp-wrap > *, .footprint-wrap > *,
.hero-grid > *, .work-grid > *, .mvv-grid > *, .commit-grid > *,
.tier-grid > *, .board-grid > *, .rings > *, .foot-grid > *,
.grid-2 > *, .grid-3 > *, .grid-4 > *{ min-width:0; }

section{ padding-block:var(--section-y); }
section.tight-top{ padding-top:0; }
section.tight-bottom{ padding-bottom:0; }

.section-head{
  display:flex; justify-content:space-between; align-items:flex-end;
  gap:var(--sp-7);
  margin-bottom:var(--sp-8);
  padding-bottom:var(--sp-5);
  border-bottom:1px solid var(--rule);
  flex-wrap:wrap;
}
/* Size in rem, never ch — ch resolves against this wrapper's body font, not
   the heading's, and silently caps every h2 at ~346px. */
.section-head > div{ flex:1 1 22rem; max-width:38rem; }
.section-head h2{ margin-top:var(--sp-4); }
.section-head > p{
  color:var(--text-soft);
  max-width:32rem; flex:0 1 24rem;
  font-size:var(--fs-sm); margin:0;
}
.section-head.center{
  flex-direction:column; align-items:center;
  text-align:center; border-bottom:none; padding-bottom:0;
}
.section-head.center > div{ max-width:42rem; }
.section-head.center .eyebrow{ justify-content:center; }

.eyebrow{
  font-family:var(--font-mono);
  font-size:var(--fs-mono);
  letter-spacing:0.2em;
  text-transform:uppercase;
  color:var(--purple);
  display:flex; align-items:center; gap:12px;
  margin:0; font-weight:400;
}
.eyebrow::before{
  content:""; width:26px; height:1px;
  background:currentColor; flex:none;
}

.lede{
  font-size:var(--fs-lede);
  color:var(--text-soft);
  line-height:1.68;
  max-width:54ch;
}

.skip-link{
  position:fixed; top:-80px; left:20px; z-index:300;
  background:var(--ink); color:var(--paper);
  padding:12px 22px; border-radius:var(--radius-sm);
  text-decoration:none; font-weight:500; font-size:var(--fs-sm);
  transition:top var(--dur) var(--ease);
}
.skip-link:focus{ top:20px; }

.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;
}

/* --------------------------------------------------------------------------
   4. HEADER / NAV
   -------------------------------------------------------------------------- */
.topbar{ background:var(--ink); color:var(--paper); }
.topbar-inner{
  display:flex; align-items:center; justify-content:center;
  gap:var(--sp-4); padding-block:10px;
  flex-wrap:wrap; text-align:center;
}
.topbar-msg{
  font-size:var(--fs-xs);
  color:rgba(255,255,255,0.72);
  letter-spacing:0.01em;
}
.topbar-donate{
  display:inline-flex; align-items:center; gap:6px;
  color:var(--paper); font-weight:500; font-size:var(--fs-xs);
  text-decoration:none;
  padding-bottom:1px;
  border-bottom:1px solid rgba(255,255,255,0.45);
  transition:border-color var(--dur) var(--ease);
}
.topbar-donate:hover{ border-color:var(--paper); }
@media (max-width:620px){ .topbar-msg{ display:none; } }

/* The blur lives on a pseudo-element, NOT on the header itself: backdrop-filter
   makes an element a containing block for position:fixed descendants, which
   would size the mobile nav panel against the 140px header instead of the
   viewport and clip it to a sliver. */
header.site{
  position:sticky; top:0; z-index:60;
  background:transparent;
  border-bottom:1px solid transparent;
  transition:border-color var(--dur) var(--ease);
}
header.site::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:rgba(255,255,255,0.9);
  backdrop-filter:blur(14px) saturate(1.3);
  -webkit-backdrop-filter:blur(14px) saturate(1.3);
}
header.site.scrolled{ border-bottom-color:var(--rule); }
header.site::after{
  content:""; position:absolute; inset:auto 0 -3px; height:3px;
  background:var(--brand-bar);
}

.nav{
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--sp-5);
  max-width:var(--maxw); margin-inline:auto;
  padding:16px var(--gutter);
}
.brand{ display:flex; align-items:center; text-decoration:none; flex:none; }
.brand .mark{ height:42px; width:auto; }

.navlinks{
  display:flex; align-items:center; gap:var(--sp-5);
  list-style:none; margin:0; padding:0;
  font-size:0.88rem; font-weight:400;
}
.navlinks a{
  position:relative;
  text-decoration:none; color:var(--text-soft);
  padding:6px 1px; white-space:nowrap;
  transition:color var(--dur) var(--ease);
}
.navlinks a:not(.navcta)::after{
  content:""; position:absolute; left:0; right:0; bottom:2px; height:1px;
  background:var(--brand-purple);
  transform:scaleX(0); transform-origin:left;
  transition:transform var(--dur) var(--ease);
}
.navlinks a:not(.navcta):hover{ color:var(--ink); }
.navlinks a:not(.navcta):hover::after,
.navlinks a.active::after{ transform:scaleX(1); }
.navlinks a.active{ color:var(--purple); }

/* Must out-specify `.navlinks a` above or the pill inherits its 1px padding. */
.navlinks a.navcta{
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--clay); color:var(--paper);
  padding:11px 24px; border-radius:var(--radius-pill);
  font-weight:500; font-size:0.85rem; line-height:1.15;
  letter-spacing:0.01em;
  transition:background var(--dur) var(--ease);
}
.navlinks a.navcta::after{ display:none; }
.navlinks a.navcta:hover{ background:var(--clay-deep); color:var(--paper); }

/* --------------------------------------------------------------------------
   Header donate button.

   Sits outside .navlinks on purpose: under 980px that list becomes an
   off-canvas panel, and a primary action hidden behind a hamburger is not a
   primary action. This stays in the bar at every width.

   On the animation — three deliberate constraints:

   1. It PULSES A FIXED NUMBER OF TIMES and then stops for good. An infinitely
      pulsing button is both irritating and an accessibility failure: WCAG 2.2.2
      requires moving content lasting more than five seconds to be pausable.
      Three pulses at 1.5s is 4.5s, under that ceiling, with no control needed.
   2. The pulse is a box-shadow ring, NOT a transform: scale. Scaling a header
      element nudges its neighbours and makes the whole bar feel unstable; a ring
      radiates outward and costs no layout.
   3. prefers-reduced-motion removes the pulse and the sheen entirely, leaving a
      plain colour change. The button is just as usable; it simply stops moving.
   -------------------------------------------------------------------------- */
.nav-donate{
  position:relative; overflow:hidden;
  display:inline-flex; align-items:center; justify-content:center;
  flex:none;
  padding:11px 26px;
  border-radius:var(--radius-pill);
  background:var(--action); color:var(--paper);
  font-family:var(--font-body); font-weight:500; font-size:0.85rem; line-height:1.15;
  letter-spacing:0.01em; text-decoration:none;
  box-shadow:0 1px 2px rgba(17,24,39,0.16);
  transition:background var(--dur) var(--ease),
             transform var(--dur) var(--ease),
             box-shadow var(--dur) var(--ease);
}
.nav-donate-label{ position:relative; z-index:2; }

.nav-donate:hover{
  background:var(--action-hover); color:var(--paper);
  transform:translateY(-1px);
  box-shadow:0 6px 18px rgba(206,36,56,0.34);
}
.nav-donate:active{ transform:translateY(0); box-shadow:0 1px 2px rgba(17,24,39,0.2); }
.nav-donate:focus-visible{ outline:2px solid var(--ink); outline-offset:3px; }

/* A sheen that crosses the button on hover. Pure transform on a pseudo-element,
   so it composites on the GPU and never triggers layout. */
.nav-donate::before{
  content:""; position:absolute; top:0; bottom:0; left:0; width:45%;
  z-index:1; pointer-events:none;
  background:linear-gradient(100deg, transparent, rgba(255,255,255,0.38), transparent);
  transform:translateX(-180%) skewX(-18deg);
  transition:transform .62s var(--ease);
}
.nav-donate:hover::before{ transform:translateX(320%) skewX(-18deg); }

/* The finite attention pulse. main.js adds .pulse a moment after load and the
   animationend handler removes it, so it can never become a permanent loop. */
.nav-donate.pulse{ animation:navDonatePulse 1.5s var(--ease) 3; }
@keyframes navDonatePulse{
  0%   { box-shadow:0 1px 2px rgba(17,24,39,0.16), 0 0 0 0 rgba(206,36,56,0.55); }
  55%  { box-shadow:0 1px 2px rgba(17,24,39,0.16), 0 0 0 12px rgba(206,36,56,0); }
  100% { box-shadow:0 1px 2px rgba(17,24,39,0.16), 0 0 0 0 rgba(206,36,56,0); }
}

@media (max-width:980px){
  /* Tighter, and it moves left of the hamburger rather than wrapping. */
  .nav-donate{ padding:10px 18px; font-size:0.82rem; margin-left:auto; }
}
@media (max-width:420px){
  .nav-donate{ padding:9px 15px; font-size:0.8rem; }
}

@media (prefers-reduced-motion:reduce){
  .nav-donate, .nav-donate::before{ transition:none; animation:none; }
  .nav-donate:hover{ transform:none; box-shadow:0 1px 2px rgba(17,24,39,0.16); }
  .nav-donate:hover::before{ transform:translateX(-180%) skewX(-18deg); }
}

.menubtn{
  display:none; background:none; border:none; cursor:pointer;
  width:44px; height:44px; align-items:center; justify-content:center;
  padding:0; flex:none;
}
.menubtn span,
.menubtn span::before,
.menubtn span::after{
  content:""; display:block; width:22px; height:1.5px;
  background:var(--ink);
  transition:transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.menubtn span{ position:relative; }
.menubtn span::before{ position:absolute; top:-7px; }
.menubtn span::after{  position:absolute; top:7px; }
.menubtn[aria-expanded="true"] span{ background:transparent; }
.menubtn[aria-expanded="true"] span::before{ transform:translateY(7px) rotate(45deg); }
.menubtn[aria-expanded="true"] span::after{  transform:translateY(-7px) rotate(-45deg); }

@media (max-width:980px){
  .menubtn{ display:flex; }
  .navlinks{
    position:fixed; inset:0 0 0 auto;
    width:min(360px, 88vw);
    background:var(--paper);
    border-left:1px solid var(--rule);
    flex-direction:column; align-items:stretch; justify-content:flex-start;
    padding:104px var(--sp-6) var(--sp-6);
    gap:0; font-size:1.05rem;
    overflow-y:auto;
    box-shadow:var(--shadow-3);
    /* Hidden state stays inside the viewport — an off-canvas translate
       creates a horizontal scrollbar on the document. */
    visibility:hidden; opacity:0; pointer-events:none;
    transform-origin:100% 50%; transform:scale(.98);
    transition:transform var(--dur) var(--ease), opacity .24s var(--ease),
               visibility 0s linear var(--dur);
  }
  .navlinks.open{
    visibility:visible; opacity:1; pointer-events:auto; transform:none;
    transition:transform var(--dur) var(--ease), opacity .24s var(--ease), visibility 0s;
  }
  .navlinks li{ width:100%; }
  .navlinks a{
    display:block; width:100%;
    padding:16px 2px;
    border-bottom:1px solid var(--rule);
  }
  .navlinks a:not(.navcta)::after{ display:none; }
  .navlinks a.navcta{
    display:flex; width:100%;
    margin-top:var(--sp-5); border-bottom:none;
    padding:16px 24px;
  }
  .nav-scrim{
    position:fixed; inset:0; z-index:55;
    background:rgba(17,24,39,0.42);
    opacity:0; pointer-events:none;
    transition:opacity var(--dur) var(--ease);
  }
  .nav-scrim.show{ opacity:1; pointer-events:auto; }
}

/* --------------------------------------------------------------------------
   5. BUTTONS
   -------------------------------------------------------------------------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  padding:15px 30px;
  border-radius:var(--radius-pill);
  font-family:var(--font-body);
  font-weight:500; font-size:0.94rem; line-height:1;
  letter-spacing:0.01em;
  text-decoration:none; cursor:pointer;
  border:1px solid transparent;
  transition:background var(--dur) var(--ease), border-color var(--dur) var(--ease),
             color var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.btn svg{ width:16px; height:16px; flex:none; }

.btn-primary{ background:var(--action); color:var(--paper); }
.btn-primary:hover{ background:var(--action-hover); }
.btn-secondary{ background:var(--purple-btn); color:var(--paper); }
.btn-secondary:hover{ background:var(--purple-deep); }
.btn-ink{ background:var(--ink); color:var(--paper); }
.btn-ink:hover{ background:var(--ink-2); }
.btn-ghost{ background:transparent; color:var(--ink); border-color:var(--rule-strong); }
.btn-ghost:hover{ border-color:var(--brand-purple); color:var(--purple); }
.btn-on-dark{ background:transparent; color:var(--paper); border-color:rgba(255,255,255,0.42); }
.btn-on-dark:hover{ background:var(--paper); color:var(--ink); border-color:var(--paper); }
.btn-block{ width:100%; }
.btn[disabled], .btn[aria-busy="true"]{ opacity:.55; pointer-events:none; }

.btn-row{ display:flex; gap:var(--sp-3); flex-wrap:wrap; align-items:center; }

.textlink{
  font-weight:500; font-size:var(--fs-sm);
  color:var(--ink); text-decoration:none;
  border-bottom:1px solid var(--rule-strong);
  padding-bottom:2px;
  transition:border-color var(--dur) var(--ease);
}
.textlink:hover{ border-color:var(--ink); }

/* --------------------------------------------------------------------------
   6. HERO
   -------------------------------------------------------------------------- */
.hero{
  position:relative; overflow:hidden;
  padding-block:clamp(64px, 6vw + 30px, 128px) clamp(56px, 5vw + 26px, 104px);
  background:
    radial-gradient(ellipse 55% 52% at 88% 4%,  rgba(3,146,212,0.24),  transparent 62%),
    radial-gradient(ellipse 46% 46% at 4% 96%,  rgba(125,74,177,0.18), transparent 60%),
    radial-gradient(ellipse 42% 40% at 60% 112%, rgba(89,179,6,0.16),  transparent 60%),
    radial-gradient(ellipse 30% 30% at 30% -6%,  rgba(223,53,72,0.11), transparent 60%),
    var(--paper);
}
.hero-grid{
  display:grid; grid-template-columns:1.12fr 0.88fr;
  gap:clamp(32px, 5vw, 72px); align-items:center;
}
.hero h1{ font-size:var(--fs-display); margin-top:var(--sp-5); }
.hero h1 em{ font-style:italic; color:var(--clay); }
.hero .lede{ margin:var(--sp-6) 0 var(--sp-7); max-width:44ch; }

.hero-stats-strip{
  margin-top:clamp(52px, 6vw, 88px);
  padding-top:var(--sp-6);
  border-top:1px solid var(--rule);
  display:grid; grid-template-columns:repeat(4,1fr);
  gap:var(--sp-6);
}
.hstat b{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.7rem, 1.25rem + 1.5vw, 2.35rem);
  color:var(--ink); display:block; line-height:1;
  letter-spacing:-0.03em;
}
/* The four headline figures carry the four logo colours in logo order. These
   use the text-safe tier, not --brand-*: the vivid green is only 2.56:1 on
   cream and would fail even at display size. */
.hstat:nth-child(1) b{ color:var(--blue); }
.hstat:nth-child(2) b{ color:var(--purple); }
.hstat:nth-child(3) b{ color:var(--green); }
.hstat:nth-child(4) b{ color:var(--red); }
.hstat span{
  font-size:var(--fs-xs); color:var(--text-soft);
  display:block; margin-top:var(--sp-3);
}

/* Ripple mark — each ring carries one logo colour, so the hero's focal
   graphic reads as the logo instead of as a grey hairline diagram. */
.ripple-wrap{
  position:relative; aspect-ratio:1/1;
  display:flex; align-items:center; justify-content:center;
}
.ripple-wrap svg{ width:100%; height:100%; overflow:visible; }
.ripple-ring{
  fill:none; stroke:var(--brand-blue); stroke-opacity:.55; stroke-width:1.5;
  transform-origin:center; transform-box:fill-box;
  animation:rippleOut 5.5s var(--ease) infinite;
}
.ripple-ring.r2{ animation-delay:1.4s; stroke:var(--brand-purple); }
.ripple-ring.r3{ animation-delay:2.8s; stroke:var(--brand-green); }
.ripple-ring.r4{ animation-delay:4.2s; stroke:var(--brand-red); }
@keyframes rippleOut{
  0%{ transform:scale(.3); opacity:0; }
  14%{ opacity:.85; }
  100%{ transform:scale(1); opacity:0; }
}
/* Core takes the wordmark's green. --green-btn, not --brand-green, because the
   cream drop sits inside it and needs 4.5:1 (the vivid green gives 2.56). */
.ripple-core{ fill:var(--green-btn); }
.ripple-core-mark{ fill:var(--paper); }

@media (max-width:920px){
  .hero-grid{ grid-template-columns:1fr; }
  .ripple-wrap{ max-width:220px; margin-inline:auto; order:-1; }
  .hero-stats-strip{ grid-template-columns:repeat(2,1fr); gap:var(--sp-6) var(--sp-5); }
}
@media (max-width:560px){
  .ripple-wrap{ max-width:150px; }
  .btn-row .btn, .btn-row .login-trigger{ flex:1 1 100%; }
}

/* Inner-page hero */
.inner-hero{
  position:relative;
  padding-block:clamp(44px, 4vw + 22px, 80px) clamp(48px, 4vw + 24px, 84px);
  background:
    radial-gradient(ellipse 50% 60% at 90% 0%, rgba(3,146,212,0.12),  transparent 62%),
    radial-gradient(ellipse 40% 50% at 2% 100%, rgba(125,74,177,0.09), transparent 60%),
    var(--paper);
  border-bottom:1px solid var(--rule);
}
.inner-hero h1{ margin-top:var(--sp-5); max-width:19ch; }
.inner-hero .lede{ margin-top:var(--sp-5); }

/* A hero with a picture beside the headline.
   NOT a 50/50 split. The text column already has its own measure — the h1 is
   capped at 19ch and the lede wants about 60 characters — so the image takes
   the space the text was never going to use. That empty right-hand third is
   exactly what this fills. */
.hero-split{
  display:grid; grid-template-columns:1.05fr 0.95fr;
  gap:clamp(32px, 5vw, 72px); align-items:center;
}
.hero-split-text > :first-child{ margin-top:0; }
.hero-split-media{
  aspect-ratio:4/3;
  border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--paper-3);
  display:flex; align-items:center; justify-content:center;
}
/* The stand-in is FILLED brand shapes, not the grey outline used elsewhere.
   The first version drew stick figures in the muted outline style of the other
   placeholders, and on a panel this size it read as cheap — which is a poor
   companion to a headline promising an institution. This is the logo's own
   language instead: a leaf and three reaching figures in the brand colours.
   Held at 0.9 so it is clearly a graphic and not a second logo competing with
   the real one in the header. */
.hero-split-media > svg{
  width:72%; max-width:320px; height:auto;
  opacity:0.9; fill:none; stroke:none;
}
.hero-split-mark .hs-leaf{ fill:var(--brand-green); opacity:0.85; }
.hero-split-mark .hs-p{ fill:var(--brand-purple); }
.hero-split-mark .hs-b{ fill:var(--brand-blue); opacity:0.92; }
.hero-split-mark .hs-r{ fill:var(--brand-red); opacity:0.92; }
.hero-split-mark .hs-ground{
  fill:none; stroke:var(--rule-strong); stroke-width:1; stroke-linecap:round;
}

/* One column on narrow screens, and the image goes UNDER the text rather than
   over it: on a phone the first thing on screen should be what the page is
   about. A picture that pushes the headline below the fold makes the page
   slower to understand, not richer. */
@media (max-width:860px){
  .hero-split{ grid-template-columns:1fr; gap:var(--sp-7); }
  .hero-split-media{ aspect-ratio:16/9; order:2; }
}

.breadcrumb{
  font-family:var(--font-mono); font-size:var(--fs-xs);
  color:var(--text-mute); margin:0 0 var(--sp-5);
}
.breadcrumb a{ text-decoration:none; color:var(--text-mute); }
.breadcrumb a:hover{ color:var(--ink); }

/* --------------------------------------------------------------------------
   7. SURFACES
   -------------------------------------------------------------------------- */
.surface-paper2{
  background:
    linear-gradient(165deg, rgba(3,146,212,0.06) 0%, rgba(125,74,177,0.045) 45%,
                    rgba(89,179,6,0.055) 100%),
    var(--paper-2);
}
.surface-ink,
.surface-purple{
  background:
    radial-gradient(ellipse 60% 70% at 90% 0%, rgba(3,146,212,0.22), transparent 60%),
    linear-gradient(140deg, var(--deep-1) 0%, var(--deep-2) 55%, var(--deep-4) 100%);
  color:rgba(255,255,255,0.82);
}

.surface-ink h1, .surface-ink h2, .surface-ink h3,
.surface-purple h1, .surface-purple h2, .surface-purple h3{ color:var(--paper); }
.surface-ink .eyebrow,
.surface-purple .eyebrow{ color:rgba(255,255,255,0.62); }
.surface-ink .section-head,
.surface-purple .section-head{ border-bottom-color:var(--rule-invert); }
.surface-ink .section-head > p,
.surface-purple .section-head > p{ color:rgba(255,255,255,0.72); }

/* --------------------------------------------------------------------------
   8. CARDS — hairline construction, no drop shadow at rest
   -------------------------------------------------------------------------- */
.card{
  background:var(--paper);
  border:1px solid var(--rule);
  border-radius:var(--radius);
  padding:var(--sp-6);
}
.card-hover{ transition:border-color var(--dur) var(--ease); }
.card-hover:hover{ border-color:var(--rule-strong); }

.grid-2{ display:grid; grid-template-columns:repeat(2,1fr); gap:var(--sp-5); }
.grid-3{ display:grid; grid-template-columns:repeat(3,1fr); gap:var(--sp-5); }
.grid-4{ display:grid; grid-template-columns:repeat(4,1fr); gap:var(--sp-5); }
@media (max-width:1000px){ .grid-4,.grid-3{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:680px){ .grid-2,.grid-3,.grid-4{ grid-template-columns:1fr; } }

/* Mission / value cards */
.mvv-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:var(--sp-5); }
.mvv-card{
  background:transparent;
  border-top:1px solid var(--rule-strong);
  border-radius:0;
  padding:var(--sp-6) var(--sp-5) var(--sp-5) 0;
  display:flex; flex-direction:column; gap:var(--sp-4);
}
.mvv-icon{
  width:38px; height:38px; border-radius:0;
  display:flex; align-items:center; justify-content:center;
  background:transparent;
}
.mvv-icon svg{
  width:26px; height:26px;
  stroke:var(--brand-blue); fill:none; stroke-width:1.4;
  stroke-linecap:round; stroke-linejoin:round;
}
.mvv-card:nth-child(2) .mvv-icon svg{ stroke:var(--brand-purple); }
.mvv-card:nth-child(3) .mvv-icon svg{ stroke:var(--brand-red); }
.mvv-card:nth-child(4) .mvv-icon svg{ stroke:var(--brand-green); }
.mvv-card h3{ margin:0; }
.mvv-card p{ margin:0; color:var(--text-soft); font-size:var(--fs-sm); }
.surface-ink .mvv-card{ border-top-color:var(--rule-invert); }
.surface-ink .mvv-card p{ color:rgba(255,255,255,0.72); }
/* Four-item variants get four columns rather than 3 + an orphan */
.mvv-grid:has(> :nth-child(4)){ grid-template-columns:repeat(4,1fr); }
@media (max-width:1080px){ .mvv-grid:has(> :nth-child(4)){ grid-template-columns:repeat(2,1fr); } }
@media (max-width:900px){
  .mvv-grid,
  .mvv-grid:has(> :nth-child(4)){ grid-template-columns:1fr; gap:0; }
}

/* --------------------------------------------------------------------------
   Impact dials — four "single ratio against a limit" meters.

   Three decisions here are measured, not stylistic:

   1. NO RED. The fourth meter used to be red, and red is a status colour: it
      reads as bad/critical. It was sitting on "Would recommend us — 91%", the
      BEST number in the row, which actively misreports the data. It is now the
      brand teal. Red still leads the donate CTA, where "act now" is the point.

   2. THE TRACK IS A LIGHT STEP OF ITS OWN HUE, not grey. A meter's state has to
      read across the whole ring, so track and fill share a ramp — blue-on-blue,
      green-on-green. The old flat grey track made the four dials look like four
      unrelated widgets.

   3. THE VIVID LOGO HUES ARE CORRECT HERE. Checked with a CVD validator: the
      vivid set (#0392D4 / #7D4AB1 / #59B306 / #0C9E8F) passes lightness,
      chroma, colour-blind separation and normal-vision separation. Substituting
      the darker text-tier values FAILS deutan separation (purple vs blue ΔE
      3.6). The one warning — vivid green at 2.6:1 against the surface — is
      discharged because every dial is directly labelled with its number.

   The number is plain HTML, not SVG <text>, for two reasons: it can carry a
   data-cms id so the client can edit it, and it is the SINGLE SOURCE OF TRUTH —
   main.js reads the percentage off this text and draws the arc from it. Edit
   "82" to "85" in the CMS and the ring follows. There is no second value to
   keep in sync.
   -------------------------------------------------------------------------- */
.rings{
  display:grid; grid-template-columns:repeat(4,1fr);
  gap:0;
  border-top:1px solid var(--rule);
}
.ring-card{
  padding:var(--sp-7) var(--sp-5);
  border-right:1px solid var(--rule);
  display:flex; flex-direction:column; align-items:center;
  text-align:center; gap:var(--sp-4);
  position:relative;
  transition:background var(--dur) var(--ease);
}
.ring-card:last-child{ border-right:none; }

/* Per-card hue. One property drives track, fill, halo and head. */
.ring-card[data-accent="blue"]  { --dial:var(--brand-blue);   --dial-deep:var(--blue);   --dial-rgb:3,146,212; }
.ring-card[data-accent="purple"]{ --dial:var(--brand-purple); --dial-deep:var(--purple); --dial-rgb:125,74,177; }
.ring-card[data-accent="green"] { --dial:var(--brand-green);  --dial-deep:var(--green);  --dial-rgb:89,179,6; }
.ring-card[data-accent="teal"]  { --dial:var(--brand-teal);   --dial-deep:var(--teal);   --dial-rgb:12,158,143; }

/* A whisper of the hue washes in behind the card on hover — the only thing
   that moves on a pointer, so the row stays calm while browsing. */
.ring-card:hover{ background:rgba(var(--dial-rgb),0.045); }

.ring-dial{
  position:relative;
  width:132px; height:132px;
  display:flex; align-items:center; justify-content:center;
}
.ring-dial svg{
  width:100%; height:100%;
  transform:rotate(-90deg);        /* 0% starts at 12 o'clock */
  overflow:visible;
}

/* The halo is what makes this read as lit rather than drawn: a wide, very faint
   stroke under the arc, revealed with it. Cheaper and crisper than a blur
   filter, which softens the arc's rounded cap on a HiDPI screen. */
.ring-halo{
  fill:none; stroke:rgba(var(--dial-rgb),0.30); stroke-width:11;
  stroke-linecap:round;
  stroke-dasharray:var(--circ, 352); stroke-dashoffset:var(--circ, 352);
  opacity:0;
  transition:stroke-dashoffset 1.25s var(--ease-dial), opacity .8s ease;
}
.ring-track{
  fill:none; stroke:rgba(var(--dial-rgb),0.16); stroke-width:5;
}
.ring-progress{
  fill:none; stroke:var(--dial); stroke-width:5; stroke-linecap:round;
  stroke-dasharray:var(--circ, 352); stroke-dashoffset:var(--circ, 352);
  transition:stroke-dashoffset 1.25s var(--ease-dial);
}
/* The travelling head. A solid dot at the arc's leading edge, rotated to the
   value — it gives the sweep somewhere to arrive and reads as a dial rather
   than a progress bar.

   The dot is authored at cx=122,cy=66 — local 3 o'clock, NOT 12. The <svg> is
   itself rotated -90deg so that 0% starts at the top, and that rotation applies
   to the dot too: a dot authored at 12 lands at 9 and trails the arc by a
   quarter turn. Authoring it at 3 puts it exactly on the arc's start. */
.ring-head{
  fill:var(--dial);
  stroke:var(--paper); stroke-width:3;
  transform:rotate(0deg); transform-origin:66px 66px; transform-box:view-box;
  transition:transform 1.25s var(--ease-dial), opacity .4s ease;
  opacity:0;
}
.ring-card.is-filled .ring-halo{ opacity:1; }
.ring-card.is-filled .ring-head{ opacity:1; }

/* Value. Sans, not the display serif: at this size a serif numeral reads as
   decoration rather than data. Proportional figures, not tabular — tabular
   gives every digit the width of a zero, which makes "82" look gappy. */
.ring-value{
  position:absolute; margin:0;
  display:flex; align-items:baseline; gap:1px;
  font-family:var(--font-body);
  letter-spacing:-0.035em;
  color:var(--text);
  font-variant-numeric:proportional-nums;
}
.ring-num{ font-size:2.05rem; font-weight:600; line-height:1; }
.ring-unit{ font-size:1rem; font-weight:500; color:var(--text-soft); }

.ring-card h3{ font-size:1rem; margin:0; }
.ring-card p{ margin:0; font-size:var(--fs-xs); color:var(--text-soft); }

/* Reduced motion: land on the final value with no sweep, no count-up, no
   travelling dot. The data still reads; nothing animates. */
@media (prefers-reduced-motion:reduce){
  .ring-halo, .ring-progress, .ring-head{ transition:none; }
}

@media (max-width:900px){
  .rings{ grid-template-columns:repeat(2,1fr); }
  .ring-card:nth-child(2){ border-right:none; }
  .ring-card:nth-child(1),.ring-card:nth-child(2){ border-bottom:1px solid var(--rule); }
}
@media (max-width:460px){
  .rings{ grid-template-columns:1fr; }
  .ring-card{ border-right:none; border-bottom:1px solid var(--rule); }
  .ring-card:last-child{ border-bottom:none; }
  .ring-dial{ width:112px; height:112px; }
  .ring-num{ font-size:1.8rem; }
}

/* --------------------------------------------------------------------------
   Homepage slider.

   Five declared slides, and the section is `hidden` in the HTML: main.js only
   reveals it if at least one slide actually has a photograph. So an empty
   slider costs the page nothing — no blank band, no layout shift, nothing for
   the client to feel bad about while they gather photos.
   -------------------------------------------------------------------------- */
.hero-slider{ padding-block:0 var(--section-y-s); background:var(--paper); }
.hero-slider[hidden]{ display:none; }

.slider-frame{ position:relative; border-radius:var(--radius-lg); overflow:hidden; background:var(--paper-3); }
.slider-track{
  list-style:none; margin:0; padding:0;
  display:flex;
  /* Scroll-snap carries the swipe on touch; the buttons scroll to a slide, so
     pointer, keyboard and finger all drive the same one mechanism. */
  overflow-x:auto; scroll-snap-type:x mandatory;
  scrollbar-width:none; -webkit-overflow-scrolling:touch;
}
.slider-track::-webkit-scrollbar{ display:none; }
.slide{ flex:0 0 100%; scroll-snap-align:center; position:relative; }
.slide[hidden]{ display:none; }
.slide-media{ aspect-ratio:16/7; width:100%; background:var(--paper-3); }
@media (max-width:700px){ .slide-media{ aspect-ratio:4/3; } }
.slide-caption{
  position:absolute; left:0; right:0; bottom:0; margin:0;
  padding:var(--sp-6) var(--sp-5) var(--sp-4);
  color:var(--paper); font-size:var(--fs-sm);
  background:linear-gradient(to top, rgba(17,24,39,0.72), rgba(17,24,39,0));
}
.slide-caption[hidden]{ display:none; }

.slider-nav{
  position:absolute; top:50%; transform:translateY(-50%);
  width:44px; height:44px; border-radius:50%;
  border:0; cursor:pointer;
  background:rgba(255,255,255,0.92); color:var(--ink);
  font-size:1.5rem; line-height:1;
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 2px 10px rgba(17,24,39,0.18);
  transition:background var(--dur) var(--ease);
}
.slider-nav:hover{ background:#fff; }
.slider-nav.prev{ left:var(--sp-4); }
.slider-nav.next{ right:var(--sp-4); }
.slider-nav[hidden]{ display:none; }

.slider-dots{
  position:absolute; left:0; right:0; bottom:var(--sp-3);
  display:flex; gap:7px; justify-content:center;
}
.slider-dots button{
  width:8px; height:8px; padding:0; border-radius:50%; border:0; cursor:pointer;
  background:rgba(255,255,255,0.55);
  transition:background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.slider-dots button[aria-selected="true"]{ background:#fff; transform:scale(1.4); }

/* Keyboard focus has to be visible on top of a photograph. */
.slider-nav:focus-visible, .slider-dots button:focus-visible{
  outline:2px solid var(--brand-blue); outline-offset:3px;
}

/* --------------------------------------------------------------------------
   Photo slots.

   The site ships 68 inline <svg> illustrations and only 2 real images, so none
   of the artwork used to be replaceable from the CMS. Each slot below is an
   <img> injected into an illustration container by server/cms/build-registry.js
   and revealed by assets/js/cms.js once an admin picks a file.

   Until then the <img> is hidden and the illustration shows as before — an
   unfilled slot is invisible, not a gap. `.has-photo` is set on the container
   when a photograph arrives, and that is what stands the placeholder down.
   -------------------------------------------------------------------------- */
.cms-photo-slot{ position:relative; overflow:hidden; }
.cms-photo{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover; object-position:center;
  display:block;
}
/* An unfilled slot ships its <img> with the `hidden` attribute, and the browser's
   own [hidden]{display:none} is a type selector — so `display:block` above beat
   it, and all 26 empty slots were laying a full-size src-less <img> over their
   illustration. Invisible, but it sat on top of the artwork and could swallow a
   click. This puts `hidden` back in charge. */
.cms-photo[hidden]{ display:none; }
/* Hide whatever the container was showing before — a line drawing, or the
   initials in an avatar circle. The tag label on a programme card stays: it
   still needs to sit over the photograph. */
.cms-photo-slot.has-photo > svg{ display:none; }
.cms-photo-slot.has-photo{ color:transparent; }
.cms-photo-slot.has-photo > .work-media-tag{
  color:var(--paper); position:relative; z-index:2;
  text-shadow:0 1px 6px rgba(17,24,39,0.55);
}
/* Circular slots (board and participant avatars) keep their ring. */
.cms-photo-round{ border-radius:50%; }
.cms-photo-round .cms-photo{ border-radius:50%; }

/* The three "what guides us" marks are the one place an admin uploads a LOGO
   rather than a photograph, and a logo cropped to fill a square is a broken
   logo — so these fit inside the box instead of covering it. The box also grows
   a little once real artwork is in it: 38px suits a 1.4px line drawing and is
   too tight for a mark that carries its own padding. */
.mvv-icon .cms-photo{ object-fit:contain; }
.mvv-icon.has-photo{ width:46px; height:46px; }

/* About-page photograph — a wide picture under the "why we exist" story.
   Empty is a legitimate state, so the container is never blank: it shows an
   outline drawing until a real photograph replaces it. */
.about-figure{ margin:var(--sp-6) 0 0; }
.about-figure-media{
  position:relative; aspect-ratio:16/9;
  border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--paper-3); overflow:hidden;
  display:flex; align-items:center; justify-content:center;
}
.about-figure-media > svg{
  /* 0.8, not 0.5: at half opacity the outline was 2.0:1 against the panel and
     read as a smudge rather than a drawing. 0.8 puts it at 3.4:1. */
  width:54%; max-width:270px; height:auto; opacity:0.8;
  stroke:var(--text-mute); fill:none; stroke-width:1.1;
  stroke-linecap:round; stroke-linejoin:round;
}
.about-figure figcaption{
  margin:var(--sp-3) 0 0;
  font-size:var(--fs-xs); color:var(--text-soft); line-height:1.6;
}

/* Program cards — quiet tinted panels, brand colour in the linework only */
.work-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:var(--sp-5); }
.work-card{
  background:var(--paper);
  border:1px solid var(--rule);
  border-radius:var(--radius);
  overflow:hidden; padding:0;
  display:flex; flex-direction:column;
  transition:border-color var(--dur) var(--ease);
}
.work-card:hover{ border-color:var(--rule-strong); }
/* Each card is capped by its own colour at full logo strength. Borders carry
   no contrast requirement, so this is where the palette can actually be
   vivid — the tint underneath has to stay legible, the cap does not. */
.work-card{ border-top:3px solid var(--card-accent, var(--rule)); }
.work-media{
  aspect-ratio:16/9; position:relative;
  display:flex; align-items:center; justify-content:center;
  border-bottom:1px solid var(--rule);
}
.work-media svg{ width:52%; height:52%; stroke-width:1.5; }
.work-card:nth-child(1){ --card-accent:var(--brand-blue);   }
.work-card:nth-child(2){ --card-accent:var(--brand-purple); }
.work-card:nth-child(3){ --card-accent:var(--brand-green);  }
.work-card:nth-child(4){ --card-accent:var(--brand-red);    }
.work-card:nth-child(5){ --card-accent:var(--brand-teal);   }
.work-card:nth-child(1) .work-media{ background:var(--tint-blue);   color:var(--brand-blue); }
.work-card:nth-child(2) .work-media{ background:var(--tint-purple); color:var(--brand-purple); }
.work-card:nth-child(3) .work-media{ background:var(--tint-green);  color:var(--brand-green); }
.work-card:nth-child(4) .work-media{ background:var(--tint-red);    color:var(--brand-red); }
.work-card:nth-child(5) .work-media{ background:var(--tint-teal);   color:var(--brand-teal); }
/* The tag is text sitting ON the tint, so it needs a step darker again than
   the on-cream text colour — the tint drops each pairing about 0.8:1. */
.work-card:nth-child(1) .work-media-tag{ color:var(--tag-blue); }
.work-card:nth-child(2) .work-media-tag{ color:var(--tag-purple); }
.work-card:nth-child(3) .work-media-tag{ color:var(--tag-green); }
.work-card:nth-child(4) .work-media-tag{ color:var(--tag-red); }
.work-card:nth-child(5) .work-media-tag{ color:var(--tag-teal); }
.work-media-tag{
  position:absolute; top:14px; left:16px;
  font-family:var(--font-mono); font-size:var(--fs-label);
  text-transform:uppercase; letter-spacing:0.16em;
  color:currentColor; opacity:.85;
}
.work-body{
  padding:var(--sp-5) var(--sp-5) var(--sp-6);
  display:flex; flex-direction:column; gap:var(--sp-3); flex:1;
}
.work-body p{ margin:0; color:var(--text-soft); font-size:var(--fs-sm); flex:1; }
.work-body .textlink{ align-self:flex-start; margin-top:var(--sp-2); }
@media (max-width:1000px){ .work-grid{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:680px){  .work-grid{ grid-template-columns:1fr; } }

/* The give-this-amount button on each cost tier. Pushed to the bottom of the
   card so the three cards stay aligned however long their descriptions run. */
.tier-card{ display:flex; flex-direction:column; }
.tier-card p{ flex:1; }
.btn-tier{ align-self:flex-start; margin-top:var(--sp-4); }

/* Board */
.board-grid{
  display:grid; grid-template-columns:repeat(4,1fr);
  gap:var(--sp-6) var(--sp-5);
}
.board-card{
  border-top:1px solid var(--rule-strong);
  padding-top:var(--sp-5);
  display:flex; flex-direction:column; gap:var(--sp-2);
}
.board-avatar{
  width:56px; height:56px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--font-mono); font-weight:400; font-size:0.8rem;
  letter-spacing:0.06em;
  color:var(--blue);
  border:1.5px solid var(--brand-blue);
  margin-bottom:var(--sp-3);
}
.board-card:nth-child(4n+2) .board-avatar{ border-color:var(--brand-purple); color:var(--purple); }
.board-card:nth-child(4n+3) .board-avatar{ border-color:var(--brand-green);  color:var(--green); }
.board-card:nth-child(4n+4) .board-avatar{ border-color:var(--brand-red);    color:var(--red); }
.board-card h3{ font-size:1.05rem; margin:0; }
.board-card .role{
  font-family:var(--font-mono); font-size:var(--fs-label);
  text-transform:uppercase; letter-spacing:0.16em;
  color:var(--text-mute); margin:0 0 var(--sp-2);
}
.board-card p:last-child{ margin:0; font-size:var(--fs-xs); color:var(--text-soft); }

/* An admin-managed board card carries an email address and up to four social
   links; the four placeholder cards in about.html carry neither, so these rules
   only ever apply to real people. */
/* The placeholder cards get their description styled by `p:last-child`; on a
   real trustee the last child is the social row, so the note needs its own
   rule to match. */
.board-bio{ margin:0; font-size:var(--fs-xs); color:var(--text-soft); }
.board-mail{ margin:0; font-size:var(--fs-xs); }
.board-mail a{
  color:var(--blue); text-decoration:none;
  border-bottom:1px solid rgba(2,118,172,0.32);
}
.board-mail a:hover, .board-mail a:focus-visible{ border-bottom-color:currentColor; }
.board-social{ display:flex; gap:9px; margin-top:var(--sp-2); }
.board-social a{
  display:inline-flex; width:27px; height:27px;
  align-items:center; justify-content:center;
  border:1px solid var(--rule-strong); border-radius:50%;
  color:var(--text-mute);
}
.board-social a:hover, .board-social a:focus-visible{
  border-color:var(--brand-blue); color:var(--blue);
}
.board-social svg{
  width:14px; height:14px;
  stroke:currentColor; fill:none;
  stroke-linecap:round; stroke-linejoin:round;
}

@media (max-width:900px){ .board-grid{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:520px){ .board-grid{ grid-template-columns:1fr; } }

/* --------------------------------------------------------------------------
   9. COMMITMENTS
   -------------------------------------------------------------------------- */
.commit-grid{
  list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:var(--sp-6) var(--sp-5);
}
.commit-card{
  position:relative;
  border-top:2px solid var(--brand-blue);
  padding:var(--sp-5) var(--sp-5) 0 0;
  display:flex; flex-direction:column; gap:var(--sp-3);
}
.commit-card:nth-child(2){ border-top-color:var(--brand-purple); }
.commit-card:nth-child(3){ border-top-color:var(--brand-green); }
.commit-card:nth-child(4){ border-top-color:var(--brand-red); }
.commit-num{
  font-family:var(--font-mono); font-size:var(--fs-mono);
  letter-spacing:0.2em; text-transform:uppercase;
  /* Tag tier, not the plain text tier. At 10.9px on the faintly tinted
     methodology section the text tier measured 4.42:1 and 4.37:1 — just under
     AA. The tag values are solved a step darker and clear it. */
  color:var(--tag-blue);
}
.commit-card:nth-child(2) .commit-num{ color:var(--tag-purple); }
.commit-card:nth-child(3) .commit-num{ color:var(--tag-green); }
.commit-card:nth-child(4) .commit-num{ color:var(--tag-red); }
.commit-card h3{ margin:0; }
.commit-card p{ margin:0; color:var(--text-soft); font-size:var(--fs-sm); }
.surface-ink .commit-card{ border-top-color:var(--rule-invert); }
.surface-ink .commit-card p{ color:rgba(255,255,255,0.72); }
@media (max-width:1000px){ .commit-grid{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:680px){  .commit-grid{ grid-template-columns:1fr; } }

/* --------------------------------------------------------------------------
   10. STORY / TRUST / STATEMENT
   -------------------------------------------------------------------------- */
.story-grid{
  display:grid; grid-template-columns:1.1fr 0.9fr;
  gap:clamp(36px, 5vw, 80px); align-items:start;
}
.story-grid .prose p{ color:var(--text-soft); line-height:1.8; margin-bottom:var(--sp-4); }
@media (max-width:920px){ .story-grid{ grid-template-columns:1fr; } }

.trust-panel{
  border-radius:var(--radius);
  padding:var(--sp-6);
  background:linear-gradient(150deg, var(--deep-1) 0%, var(--deep-3) 100%);
  color:rgba(255,255,255,0.85);
}
/* These were four rules in two duplicate pairs, and the duplication was a real
   bug: the later `.trust-panel dt{ color:var(--text-mute) }` overrode the
   earlier `rgba(255,255,255,0.6)`, so the labels rendered dark grey on the deep
   purple panel — 2.0:1, effectively unreadable. Merged, inverted colour kept.
   This predates the palette change; the old cream tokens failed here too. */
.trust-panel h3{ color:var(--paper); margin-bottom:var(--sp-5); }
.trust-panel dl{ display:grid; gap:var(--sp-4); margin:0; }
.trust-panel dt{
  font-family:var(--font-mono); font-size:var(--fs-label);
  text-transform:uppercase; letter-spacing:0.16em;
  color:rgba(255,255,255,0.66); margin-bottom:5px;
}
.trust-panel dd{ margin:0; font-weight:500; font-size:var(--fs-sm); color:var(--paper); }


.statement{
  font-family:var(--font-display); font-weight:400; font-style:italic;
  font-size:clamp(1.45rem, 1.05rem + 1.7vw, 2.15rem);
  line-height:1.36; letter-spacing:-0.02em;
  margin:0 0 var(--sp-6); color:var(--paper);
}
.body-invert{ color:rgba(255,255,255,0.78); }
.body-invert a{ color:var(--paper); text-decoration:underline; text-underline-offset:3px; }

.fact-list{ list-style:none; margin:0; padding:0; display:grid; }
.fact-list li{
  display:grid; grid-template-columns:5.5rem 1fr; gap:var(--sp-4);
  padding:var(--sp-5) 0;
  border-top:1px solid var(--rule-invert);
  font-size:var(--fs-sm); color:rgba(255,255,255,0.8);
}
.fact-list li:first-child{ padding-top:0; border-top:none; }
.fact-list b{
  color:rgba(255,255,255,0.55); font-family:var(--font-mono);
  font-weight:400; font-size:var(--fs-mono);
  text-transform:uppercase; letter-spacing:0.16em;
  padding-top:5px;
}
@media (max-width:520px){ .fact-list li{ grid-template-columns:1fr; gap:var(--sp-2); } }

/* --------------------------------------------------------------------------
   11. VOICES — editorial pull-quotes on light
   -------------------------------------------------------------------------- */
.voice-track{
  display:flex; gap:var(--sp-5);
  overflow-x:auto; padding-bottom:var(--sp-4);
  scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch;
  scrollbar-width:thin;
}
.voice-track::-webkit-scrollbar{ height:2px; }
.voice-track::-webkit-scrollbar-track{ background:var(--rule); }
.voice-track::-webkit-scrollbar-thumb{ background:var(--rule-strong); }
.voice-card{
  scroll-snap-align:start; flex:0 0 min(330px, 80vw);
  border-top:1px solid var(--rule-strong);
  padding:var(--sp-5) 0 0;
  display:flex; flex-direction:column; gap:var(--sp-5);
}
.voice-card blockquote{
  font-family:var(--font-display); font-style:italic; font-weight:400;
  font-size:1.12rem; line-height:1.5; letter-spacing:-0.01em;
  margin:0; color:var(--ink);
}
.voice-who{ display:flex; align-items:center; gap:var(--sp-3); margin-top:auto; }
.avatar{
  width:38px; height:38px; border-radius:50%; flex:none;
  display:flex; align-items:center; justify-content:center;
  border:1.5px solid var(--brand-blue); color:var(--blue);
  font-family:var(--font-mono); font-weight:400; font-size:0.7rem;
}
.voice-card:nth-child(2) .avatar{ border-color:var(--brand-purple); color:var(--purple); }
.voice-card:nth-child(3) .avatar{ border-color:var(--brand-green);  color:var(--green); }
.voice-card:nth-child(4) .avatar{ border-color:var(--brand-red);    color:var(--red); }
.voice-who b{ display:block; font-size:var(--fs-sm); font-weight:500; color:var(--ink); }
.voice-who span{ font-size:var(--fs-xs); color:var(--text-mute); }

/* --------------------------------------------------------------------------
   12. CTA BAND + BANK DETAILS
   -------------------------------------------------------------------------- */
.ctaband{
  background:linear-gradient(120deg, var(--blue-deep) 0%, var(--blue-btn) 38%, var(--purple-deep) 100%);
  padding-block:var(--section-y-s);
}
.ctaband h2{ color:var(--paper); }
.ctaband .btn-primary{ background:var(--paper); color:var(--ink); }
.ctaband .btn-primary:hover{ background:var(--paper-3); }
.ctaband .btn-ghost{ color:var(--paper); border-color:rgba(255,255,255,0.45); }
.ctaband .btn-ghost:hover{ background:rgba(255,255,255,0.12); border-color:var(--paper); color:var(--paper); }
.ctaband-head{
  display:flex; align-items:flex-end; justify-content:space-between;
  gap:var(--sp-6); flex-wrap:wrap;
}
.ctaband h2{ max-width:22ch; }
.surface-ink.ctaband,
.ctaband.surface-ink h2{ color:var(--paper); }

.bank-details{
  margin-top:var(--sp-6); margin-bottom:0;
  border:1px solid var(--rule);
  border-radius:var(--radius);
  background:var(--paper);
  padding:var(--sp-5) var(--sp-6);
  display:grid; grid-template-columns:repeat(4,1fr);
  gap:var(--sp-5);
}
.bank-details > div{ min-width:0; }
.bank-details dt{
  font-family:var(--font-mono); font-size:var(--fs-label);
  text-transform:uppercase; letter-spacing:0.16em;
  color:var(--text-mute); margin-bottom:7px;
}
.bank-details dd{
  margin:0; font-weight:500; font-size:var(--fs-sm);
  color:var(--ink); overflow-wrap:anywhere;
}
.surface-ink .bank-details{
  background:transparent; border-color:var(--rule-invert);
}
.surface-ink .bank-details dt{ color:rgba(255,255,255,0.55); }
.surface-ink .bank-details dd{ color:var(--paper); }
@media (max-width:900px){ .bank-details{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:460px){ .bank-details{ grid-template-columns:1fr; } }

/* Donate tiers */
.tier-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:var(--sp-5); }
.tier-card{
  border-top:2px solid var(--brand-blue);
  padding:var(--sp-5) var(--sp-5) 0 0;
  display:flex; flex-direction:column; gap:var(--sp-3);
}
.tier-card:nth-child(2){ border-top-color:var(--brand-purple); }
.tier-card:nth-child(3){ border-top-color:var(--brand-green); }
.tier-amount{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(2rem, 1.5rem + 1.7vw, 2.7rem);
  color:var(--ink); line-height:1; letter-spacing:-0.035em;
}
.tier-card h3{ margin:0; }
.tier-card p{ margin:0; color:var(--text-soft); font-size:var(--fs-sm); flex:1; }
@media (max-width:820px){ .tier-grid{ grid-template-columns:1fr; } }

/* --------------------------------------------------------------------------
   13. FORMS
   -------------------------------------------------------------------------- */
.form-card{
  background:var(--paper);
  border:1px solid var(--rule);
  border-radius:var(--radius);
  padding:clamp(26px, 3.2vw, 44px);
}
.surface-paper2 .form-card{ background:var(--paper); }
.form-grid{ display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-4) var(--sp-5); }
.field{ display:flex; flex-direction:column; gap:8px; min-width:0; }
.field.full{ grid-column:1 / -1; }
.field label{
  font-size:var(--fs-xs); font-weight:500; color:var(--ink);
  letter-spacing:0.01em;
}
fieldset.field{ border:none; padding:0; margin:0; }
.field-legend{
  font-size:var(--fs-xs); font-weight:500; color:var(--ink);
  letter-spacing:0.01em; padding:0; margin-bottom:9px;
}
/* A single form shouldn't run the full 1180px measure */
.narrow-block{ max-width:58rem; margin-inline:auto; }
.field .req{ color:var(--clay); }
.field > input,
.field > select,
.field > textarea{
  font-family:var(--font-body); font-size:0.95rem; color:var(--text);
  padding:13px 15px;
  border-radius:var(--radius-sm);
  border:1px solid var(--rule-strong);
  background:var(--paper);
  outline:none; width:100%;
  transition:border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.field > input::placeholder,
.field > textarea::placeholder{ color:var(--text-mute); }
.field > input:hover, .field > select:hover, .field > textarea:hover{ border-color:var(--text-mute); }
.field > input:focus, .field > select:focus, .field > textarea:focus{
  border-color:var(--ink);
  box-shadow:0 0 0 3px rgba(17,24,39,0.07);
}
.field > textarea{ resize:vertical; min-height:118px; }
.field > select{
  appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%235B6870' stroke-width='1.3' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 15px center;
  padding-right:40px;
}
.field-error{ font-size:var(--fs-xs); color:var(--clay-deep); font-weight:500; display:none; }
.field.invalid > input,
.field.invalid > select,
.field.invalid > textarea{ border-color:var(--clay); }
.field.invalid > input:focus,
.field.invalid > select:focus,
.field.invalid > textarea:focus{ box-shadow:0 0 0 3px rgba(206,36,56,0.14); }
.field.invalid .field-error{ display:block; }

.checkbox-group{ display:flex; flex-wrap:wrap; gap:10px; }
.chip-check{
  display:inline-flex; align-items:center; gap:10px;
  /* flex:none is load-bearing — as shrinkable items these wrap their labels
     onto three lines and the pill radius turns them into giant ovals. */
  flex:0 0 auto; max-width:100%;
  white-space:nowrap;
  padding:9px 18px 9px 14px; border-radius:var(--radius-pill);
  border:1px solid var(--rule-strong);
  font-size:var(--fs-xs); line-height:1.4; cursor:pointer;
  background:transparent; user-select:none;
  transition:border-color .18s var(--ease), background .18s var(--ease);
}
.chip-check:hover{ border-color:var(--text-mute); }
.chip-check input{
  appearance:none; -webkit-appearance:none;
  width:15px; height:15px; margin:0; flex:none;
  border:1px solid var(--rule-strong); border-radius:4px;
  background:transparent; position:relative; cursor:pointer;
  transition:background .16s var(--ease), border-color .16s var(--ease);
}
.chip-check input:checked{ background:var(--ink); border-color:var(--ink); }
.chip-check input:checked::after{
  content:""; position:absolute; left:4.5px; top:1.5px;
  width:4px; height:8px;
  border:solid var(--paper); border-width:0 1.5px 1.5px 0;
  transform:rotate(42deg);
}
.chip-check:has(input:checked){ border-color:var(--ink); background:rgba(17,24,39,0.035); }
.chip-check:has(input:focus-visible){ outline:2px solid var(--ink); outline-offset:2px; }
@media (max-width:420px){ .chip-check{ white-space:normal; } }

.hp-field{
  position:absolute !important; left:-9999px !important;
  width:1px; height:1px; overflow:hidden;
}

.form-submit{
  margin-top:var(--sp-6);
  display:flex; align-items:center; gap:var(--sp-4); flex-wrap:wrap;
}
.form-note{ font-size:var(--fs-xs); color:var(--text-mute); margin:var(--sp-4) 0 0; }
.form-alert{
  display:none; margin-top:var(--sp-4);
  padding:14px 18px; border-radius:var(--radius-sm);
  font-size:var(--fs-sm); line-height:1.55;
  border:1px solid;
}
.form-alert.show{ display:block; }
.form-alert.success{ background:var(--tint-ok);  border-color:rgba(65,127,5,0.32);  color:var(--green-deep); }
.form-alert.error{   background:var(--tint-err); border-color:rgba(206,36,56,0.32); color:var(--clay-deep); }
.spinner{
  width:14px; height:14px; border-radius:50%;
  border:1.5px solid rgba(255,255,255,0.35); border-top-color:var(--paper);
  animation:spin .7s linear infinite; display:none;
}
[aria-busy="true"] .spinner{ display:block; }
@keyframes spin{ to{ transform:rotate(360deg); } }

@media (max-width:620px){ .form-grid{ grid-template-columns:1fr; } }

/* --------------------------------------------------------------------------
   14. MODAL
   -------------------------------------------------------------------------- */
.login-trigger{
  display:inline-flex; align-items:center; gap:8px;
  background:transparent; border:1px solid var(--rule-strong);
  color:var(--ink); font-family:var(--font-body);
  border-radius:var(--radius-pill); padding:14px 26px;
  font-size:0.94rem; font-weight:500; cursor:pointer; line-height:1;
  transition:border-color var(--dur) var(--ease);
}
.login-trigger:hover{ border-color:var(--ink); }

.modal-overlay{
  position:fixed; inset:0; z-index:200;
  background:rgba(17,24,39,0.55);
  backdrop-filter:blur(4px);
  display:none; align-items:center; justify-content:center;
  padding:var(--sp-5);
}
.modal-overlay.open{ display:flex; }
.modal-panel{
  background:var(--paper); border-radius:var(--radius);
  padding:var(--sp-7) var(--sp-6) var(--sp-6);
  max-width:420px; width:100%; position:relative;
  box-shadow:var(--shadow-3);
  max-height:90vh; overflow-y:auto;
}
.modal-close{
  position:absolute; top:18px; right:18px;
  background:none; border:none; cursor:pointer;
  width:34px; height:34px;
  display:flex; align-items:center; justify-content:center;
  border-radius:50%; color:var(--text-soft);
  transition:color var(--dur) var(--ease);
}
.modal-close:hover{ color:var(--ink); }
.modal-panel h3{ font-size:1.3rem; margin-bottom:6px; }
.modal-sub{ color:var(--text-soft); font-size:var(--fs-sm); margin:0 0 var(--sp-5); }
.modal-panel .field{ margin-bottom:var(--sp-4); }
.modal-note{
  margin:var(--sp-5) 0 0; font-size:var(--fs-xs);
  color:var(--text-mute); line-height:1.6;
  padding-top:var(--sp-4); border-top:1px solid var(--rule);
}

/* --------------------------------------------------------------------------
   15. PRESS
   -------------------------------------------------------------------------- */
.press-list{ display:grid; border-top:1px solid var(--rule); }
.press-card{
  display:grid; grid-template-columns:9rem 1fr; gap:var(--sp-6);
  padding:var(--sp-6) 0;
  border-bottom:1px solid var(--rule);
  align-items:start;
}
.press-date{
  font-family:var(--font-mono); font-size:var(--fs-xs);
  color:var(--text-mute); line-height:1.6; padding-top:3px;
}
.press-tag{
  font-family:var(--font-mono); font-size:var(--fs-label);
  text-transform:uppercase; letter-spacing:0.16em;
  color:var(--green); display:inline-block; margin-bottom:var(--sp-3);
}
.press-card h3{ margin-bottom:var(--sp-3); }
.press-card p{ margin:0 0 var(--sp-4); color:var(--text-soft); font-size:var(--fs-sm); }
@media (max-width:640px){ .press-card{ grid-template-columns:1fr; gap:var(--sp-3); } }

.note-box{
  text-align:center; padding:var(--sp-7) var(--sp-5);
  border:1px solid var(--rule); border-radius:var(--radius);
  color:var(--text-soft); font-size:var(--fs-sm);
}

/* Empty state for a list that is genuinely empty. The three press cards that
   used to sit here were invented examples whose body copy was instructions to
   the client ("Replace with a short summary…"), published to the public. An
   honest blank beats fabricated coverage on a non-profit that solicits
   donations. assets/js/content.js rebuilds .press-list from the CMS as soon as
   real items exist, so this is only ever the fallback. */
.press-empty{
  margin:0; padding:var(--sp-6) 0;
  color:var(--text-soft); font-size:var(--fs-lede);
  border-top:1px solid var(--rule);
}

/* --------------------------------------------------------------------------
   16. CHAIRPERSON
   -------------------------------------------------------------------------- */
.cp-wrap{
  display:grid; grid-template-columns:0.62fr 1.38fr;
  gap:clamp(34px, 5vw, 72px); align-items:start;
}
.cp-portrait{
  aspect-ratio:4/5; border-radius:var(--radius);
  border:1px solid var(--rule);
  display:flex; align-items:center; justify-content:center;
  overflow:hidden; position:sticky; top:120px;
}
.cp-portrait .ph{
  width:100%; height:100%;
  display:flex; align-items:center; justify-content:center;
  flex-direction:column; gap:var(--sp-4);
  color:var(--text-mute); font-size:var(--fs-xs);
  text-align:center; padding:var(--sp-5);
}
.cp-portrait .ph svg{ width:44px; height:44px; stroke:var(--text-mute); fill:none; stroke-width:1; }
.cp-message p{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.1rem, 1rem + 0.5vw, 1.34rem);
  line-height:1.78; color:var(--ink-2); margin:0 0 var(--sp-5);
}
.cp-message p:first-of-type::first-letter{
  font-size:3.6rem; font-weight:400; float:left;
  line-height:.76; margin:10px 14px 0 0; color:var(--clay);
  font-family:var(--font-display);
}
.cp-sign{
  margin-top:var(--sp-7); padding-top:var(--sp-5);
  border-top:1px solid var(--rule);
  display:flex; align-items:center; gap:var(--sp-4);
}
.cp-sign-mark{
  font-family:var(--font-display); font-style:italic;
  font-size:1.6rem; color:var(--text-mute);
}
.cp-sign b{ display:block; font-size:0.96rem; font-weight:500; color:var(--ink); }
.cp-sign span{ font-size:var(--fs-xs); color:var(--text-soft); }
@media (max-width:920px){
  .cp-wrap{ grid-template-columns:1fr; }
  .cp-portrait{ max-width:240px; position:static; }
}

/* --------------------------------------------------------------------------
   17. CONTACT
   -------------------------------------------------------------------------- */
.contact-grid{
  display:grid; grid-template-columns:1.08fr 0.92fr;
  gap:clamp(32px, 4vw, 64px); align-items:start;
}
.contact-info-card{
  background:linear-gradient(150deg, var(--deep-1) 0%, var(--deep-3) 100%);
  color:rgba(255,255,255,0.85);
  border-radius:var(--radius); padding:var(--sp-6);
}
.contact-info-card h3{ color:var(--paper); margin-bottom:var(--sp-5); }
.contact-row{
  display:flex; gap:var(--sp-4);
  padding:var(--sp-4) 0;
  border-top:1px solid var(--rule-invert);
  font-size:var(--fs-sm);
}
.contact-row:first-of-type{ border-top:none; padding-top:0; }
.contact-row .ci{
  width:18px; height:18px; flex:none;
  stroke:var(--brand-blue); fill:none; stroke-width:1.5; margin-top:4px;
}
.contact-row b{
  display:block; font-size:var(--fs-label);
  text-transform:uppercase; letter-spacing:0.16em;
  font-family:var(--font-mono);
  color:rgba(255,255,255,0.55); margin-bottom:5px; font-weight:400;
}
.contact-row a{ color:var(--paper); text-decoration:none; border-bottom:1px solid var(--rule-invert); }
.contact-row a:hover{ border-color:var(--paper); }
@media (max-width:920px){ .contact-grid{ grid-template-columns:1fr; } }

/* --------------------------------------------------------------------------
   18. FOOTPRINT MAP
   -------------------------------------------------------------------------- */
.footprint-wrap{
  display:grid; grid-template-columns:1fr 1fr;
  gap:clamp(34px, 4vw, 64px); align-items:center;
}
.india-map-panel{
  border:1px solid var(--rule); border-radius:var(--radius);
  padding:var(--sp-6);
  display:flex; align-items:center; justify-content:center;
}
.india-map-panel svg{ width:100%; max-width:330px; height:auto; margin-inline:auto; }
.india-shape{ fill:rgba(17,24,39,0.035); stroke:var(--ink); stroke-width:1; stroke-opacity:.25; }
.india-pin circle.dot{ fill:var(--brand-red); }
.india-pin circle.pulse{
  fill:none; stroke:var(--clay); stroke-width:1; opacity:.6;
  transform-origin:center; transform-box:fill-box;
  animation:pinPulse 3s ease-out infinite;
}
@keyframes pinPulse{
  0%{ transform:scale(.6); opacity:.7; }
  100%{ transform:scale(2.6); opacity:0; }
}
.india-pin text{
  font-family:var(--font-mono); font-size:6px;
  fill:var(--text-soft); font-weight:400;
}
.map-caption{
  text-align:center; font-size:var(--fs-xs);
  color:var(--text-soft); margin:var(--sp-5) 0 0;
}
.footprint-list{ display:grid; grid-template-columns:1fr 1fr; gap:0 var(--sp-6); margin-top:var(--sp-6); }
.footprint-list div{
  display:flex; align-items:center; gap:12px;
  font-size:var(--fs-sm); color:var(--text);
  padding:12px 0; border-bottom:1px solid var(--rule);
}
.fp-dot{ width:6px; height:6px; border-radius:50%; background:var(--brand-red); flex:none; }
@media (max-width:920px){ .footprint-wrap{ grid-template-columns:1fr; } }
@media (max-width:520px){ .footprint-list{ grid-template-columns:1fr; } }

/* --------------------------------------------------------------------------
   19. FOOTER
   -------------------------------------------------------------------------- */
footer.site::before{
  content:""; position:absolute; inset:0 0 auto; height:3px;
  background:var(--brand-bar);
}
footer.site{
  position:relative;
  background:linear-gradient(160deg, var(--ink) 0%, var(--deep-5) 60%, var(--deep-4) 100%);
  color:rgba(255,255,255,0.72);
  padding-block:var(--sp-9) var(--sp-6);
}
.foot-grid{
  display:grid; grid-template-columns:1.6fr 1fr 1fr 1fr;
  gap:var(--sp-7);
  padding-bottom:var(--sp-8);
  border-bottom:1px solid var(--rule-invert);
}
.foot-mark{
  height:52px; width:auto; background:var(--paper);
  padding:8px 14px; border-radius:var(--radius-sm);
  margin-bottom:var(--sp-5);
}
.foot-about{
  font-size:var(--fs-sm); line-height:1.7;
  max-width:32ch; color:rgba(255,255,255,0.66);
}
.foot-reg{
  font-size:var(--fs-xs); color:rgba(255,255,255,0.5);
  margin:var(--sp-4) 0 0; line-height:1.9;
}
.foot-reg b{ color:rgba(255,255,255,0.78); font-weight:500; }
.foot-col h4{
  font-family:var(--font-mono); font-size:var(--fs-label);
  letter-spacing:0.2em; text-transform:uppercase;
  color:rgba(255,255,255,0.5); margin:0 0 var(--sp-5); font-weight:400;
}
.foot-col ul{ list-style:none; margin:0; padding:0; display:grid; gap:13px; }
.foot-col li{ font-size:var(--fs-sm); line-height:1.6; color:rgba(255,255,255,0.66); }
.foot-col a{
  text-decoration:none; font-size:var(--fs-sm);
  color:rgba(255,255,255,0.78);
  transition:color var(--dur) var(--ease);
}
.foot-col a:hover{ color:var(--paper); }
.foot-bottom{
  display:flex; justify-content:space-between; align-items:center;
  flex-wrap:wrap; gap:var(--sp-4);
  padding-top:var(--sp-5);
  font-size:var(--fs-xs); color:rgba(255,255,255,0.5);
}
.foot-social{ display:flex; gap:var(--sp-4); }
.foot-social a{
  display:flex; width:34px; height:34px;
  align-items:center; justify-content:center;
  border-radius:50%; border:1px solid var(--rule-invert);
  transition:border-color var(--dur) var(--ease);
}
.foot-social a svg{ width:16px; height:16px; stroke:rgba(255,255,255,0.66); fill:none; }
.foot-social a:hover{ border-color:rgba(255,255,255,0.5); }
.foot-social a:hover svg{ stroke:var(--paper); }
@media (max-width:920px){ .foot-grid{ grid-template-columns:1fr 1fr; row-gap:var(--sp-7); } }
@media (max-width:520px){
  .foot-grid{ grid-template-columns:1fr; }
  .ctaband-head{ align-items:flex-start; }
}

/* --------------------------------------------------------------------------
   20. PENDING-CONTENT FLAG
   Marks sections awaiting real client data. Delete the element to remove.
   -------------------------------------------------------------------------- */
/* Block, not flex: these notes contain inline <code>, and in a flex container
   each text run becomes its own item, laying the sentence out in columns. */
.pending{
  display:block; position:relative;
  border:1px dashed var(--rule-strong);
  border-radius:var(--radius-sm);
  padding:11px 16px 11px 36px;
  font-family:var(--font-mono); font-size:0.7rem; line-height:1.7;
  color:var(--text-soft); letter-spacing:0.02em;
  max-width:74ch; background:transparent;
}
.pending::before{
  content:"◇"; position:absolute; left:15px; top:12px;
  font-size:0.62rem; line-height:1.7;
}
.pending code{ font-family:inherit; color:var(--ink); }
.pending-block{ margin-top:var(--sp-5); }
.surface-ink .pending code{ color:var(--paper); }
.pending-inline{
  font-family:var(--font-mono); font-size:0.72rem;
  color:var(--text-mute); border-bottom:1px dashed var(--rule-strong);
  white-space:nowrap;
}
.surface-ink .pending{
  border-color:var(--rule-invert); color:rgba(255,255,255,0.62);
}
.surface-ink .pending-inline,
/* The contact info card is a dark gradient panel but is not .surface-ink, so it
   never picked up the inverted colour and rendered --text-mute at 2.2:1. */
.contact-info-card .pending-inline,
.trust-panel .pending-inline{ color:rgba(255,255,255,0.62); border-bottom-color:var(--rule-invert); }

/* --------------------------------------------------------------------------
   21. SCROLL REVEAL + UTILITIES
   -------------------------------------------------------------------------- */
.reveal{
  opacity:0; transform:translateY(12px);
  transition:opacity .7s var(--ease), transform .7s var(--ease);
}
.reveal.in{ opacity:1; transform:none; }
.reveal-fade{ opacity:0; transition:opacity .7s ease; }
.reveal-fade.in{ opacity:1; }
@media (prefers-reduced-motion: reduce){
  .reveal, .reveal-fade{ opacity:1 !important; transform:none !important; }
}

.center{ text-align:center; }
.mt-0{ margin-top:0; }
.mt-4{ margin-top:var(--sp-4); }
.mt-5{ margin-top:var(--sp-5); }
.mt-6{ margin-top:var(--sp-6); }
.mb-6{ margin-bottom:var(--sp-6); }
.mb-8{ margin-bottom:var(--sp-8); }
.muted{ color:var(--text-soft); }
.stack-center{
  display:flex; flex-direction:column; align-items:center;
  text-align:center; gap:var(--sp-4);
}
.stack-center p{ max-width:50ch; }
.surface-ink .muted{ color:rgba(255,255,255,0.72); }


/* --------------------------------------------------------------------------
   22. MOBILE ERGONOMICS
   Small mono labels and inline links are legible/tappable at desktop size but
   fall under 11px text and 32px touch targets on a phone. Scale them up here
   rather than compromising the desktop typography.
   -------------------------------------------------------------------------- */
@media (max-width:820px){
  :root{
    --fs-mono:  0.74rem;
    --fs-label: 0.72rem;
    --fs-xs:    0.85rem;
  }

  /* Touch targets — 40px minimum on anything tappable */
  .topbar-donate{ padding:9px 2px; }
  .textlink{ display:inline-block; padding-block:9px; }
  .breadcrumb{ line-height:2.4; }
  .breadcrumb a{ display:inline-block; padding-block:7px; }
  .foot-col ul{ gap:2px; }
  .foot-col a{ display:inline-block; padding-block:10px; }
  .foot-col li{ padding-block:2px; }
  .contact-row a{ display:inline-block; padding-block:6px; }
  .foot-social a{ width:42px; height:42px; }
  .modal-close{ width:42px; height:42px; top:12px; right:12px; }
  .chip-check{ padding-block:12px; }
  .field > input, .field > select, .field > textarea{ padding:14px 15px; font-size:16px; }
  .btn{ padding:16px 30px; }

  /* Readability */
  .pending{ font-size:0.76rem; }
  .pending-inline{ font-size:0.76rem; }
  .avatar{ font-size:0.76rem; width:42px; height:42px; }
  .map-caption{ font-size:var(--fs-xs); }
}

/* Never let a 16px form field trigger iOS zoom-on-focus */
@media (max-width:820px) and (hover:none){
  .field > input, .field > select, .field > textarea{ font-size:16px; }
}
