/* =========================================================================
   UBS Charitable Foundation — design system
   Concept: "A memorial, kept alive."
   Warm paper, deep ink, editorial serif.
   ========================================================================= */

/* ---------- Fonts (self-hosted, no third-party requests) ---------- */
@font-face {
  font-family: 'Fraunces';
  src: url('../fonts/fraunces.woff2') format('woff2-variations');
  font-weight: 300 800;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF;
}
@font-face {
  font-family: 'Karla';
  src: url('../fonts/karla.woff2') format('woff2-variations');
  font-weight: 300 700;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF;
}
/* Devanagari companions — पंख and समुत्कर्ष are names, not decoration. */
@font-face {
  font-family: 'Tiro Devanagari Hindi';
  src: url('../fonts/tiro-deva.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FF;
}
@font-face {
  font-family: 'Mukta';
  src: url('../fonts/mukta-deva.woff2') format('woff2');
  font-weight: 300 600;
  font-display: swap;
  unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FF;
}

/* ---------- Tokens ---------- */
:root {
  /* Paper & ink */
  --paper:        #FAF6EF;
  --paper-warm:   #F3ECE0;
  --paper-deep:   #EAE0D0;
  --ink:          #1B1F2A;
  --ink-soft:     #4E5566;
  --ink-faint:    #666975;   /* WCAG AA on paper and paper-warm */

  /* Brand — sampled from the logo */
  --blue:         #33578C;
  --blue-deep:    #1C3157;
  --blue-tint:    #E4EAF3;
  --gold:         #C68B26;   /* brand gold — surfaces and borders only */
  --gold-text:    #8E631B;   /* AA-compliant gold for text on paper */
  --gold-bright:  #E3A93C;
  --gold-tint:    #F6E7C6;

  /* Pillars — muted, earthen, never shouty */
  --edu:          #A9552A;
  --women:        #86466A;
  --seniors:      #33578C;
  --env:          #4C6B37;

  --line:         #DCD2C1;
  --line-strong:  #C3B79F;

  /* Type */
  --display: 'Fraunces', 'Tiro Devanagari Hindi', Georgia, serif;
  --body:    'Karla', 'Mukta', -apple-system, BlinkMacSystemFont, sans-serif;
  --deva:    'Tiro Devanagari Hindi', 'Mukta', serif;

  /* Fluid scale */
  --step--2: clamp(0.71rem, 0.68rem + 0.13vw, 0.78rem);
  --step--1: clamp(0.84rem, 0.80rem + 0.19vw, 0.94rem);
  --step-0:  clamp(1.00rem, 0.95rem + 0.26vw, 1.13rem);
  --step-1:  clamp(1.19rem, 1.11rem + 0.38vw, 1.41rem);
  --step-2:  clamp(1.41rem, 1.30rem + 0.57vw, 1.76rem);
  --step-3:  clamp(1.69rem, 1.51rem + 0.86vw, 2.20rem);
  --step-4:  clamp(2.00rem, 1.75rem + 1.27vw, 2.75rem);
  --step-5:  clamp(2.38rem, 2.01rem + 1.85vw, 3.43rem);
  --step-6:  clamp(2.83rem, 2.30rem + 2.66vw, 4.29rem);
  --step-7:  clamp(3.36rem, 2.60rem + 3.79vw, 5.36rem);

  /* Space */
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --section: clamp(4rem, 9vw, 8.5rem);
  --measure: 62ch;

  --radius: 2px;
  --shadow-lift: 0 1px 2px rgba(27,31,42,.05), 0 12px 32px -12px rgba(27,31,42,.18);
  --ease: cubic-bezier(.22,.61,.36,1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  font-family: var(--body);
  font-size: var(--step-0);
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Paper grain. Subtle — you should feel it, not see it. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: .32;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

img, picture, svg, video { display: block; max-width: 100%; height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }

/* ---------- Typography ---------- */
h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 500;
  line-height: 1.06;
  letter-spacing: -0.022em;
  font-variation-settings: 'SOFT' 20, 'opsz' 100;
  text-wrap: balance;
}
h1 { font-size: var(--step-6); }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-2); letter-spacing: -0.014em; }
h4 { font-size: var(--step-1); letter-spacing: -0.008em; }

p { text-wrap: pretty; }
p + p { margin-top: 1em; }

/* Devanagari inline — set it properly, at its own optical size */
:lang(hi), .deva {
  font-family: var(--deva);
  font-feature-settings: 'kern' 1;
  line-height: 1.5;
}
/* Inline Devanagari inside a heading: em resolves against the heading — correct. */
h1 :lang(hi), h2 :lang(hi), h3 :lang(hi) { font-size: 0.92em; letter-spacing: 0; }

/* A heading that is ITSELF Devanagari needs an absolute size — `em` here would
   resolve against the parent block, not the heading, and collapse to body size. */
h1.deva { font-size: calc(var(--step-6) * 0.94); letter-spacing: 0; }
h2.deva { font-size: calc(var(--step-4) * 0.94); letter-spacing: 0; }
h3.deva { font-size: calc(var(--step-2) * 0.94); letter-spacing: 0; }

a { color: inherit; text-decoration-color: var(--line-strong); text-underline-offset: 0.22em; text-decoration-thickness: 1px; }
a:hover { text-decoration-color: var(--gold); }

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

/* ---------- Utilities ---------- */
.wrap { width: min(100% - (var(--gutter) * 2), 1240px); margin-inline: auto; }
.wrap--narrow { width: min(100% - (var(--gutter) * 2), 820px); margin-inline: auto; }
.measure { max-width: var(--measure); }

/* Clips an image that scales or drifts inside a fixed frame, without clipping
   any decoration positioned outside the figure. */
.frame, .ph { display: block; overflow: hidden; border-radius: var(--radius); }

/* Two-column editorial splits used across inner pages */
@media (min-width: 860px) {
  .two-col       { grid-template-columns: 1fr 1fr; }
  /* Alternating blocks put the picture on the right — but only once there
     are two columns, so the stacked order stays picture-then-text. */
  .two-col > figure.flip { order: 2; }
  .mission-grid  { grid-template-columns: 1fr 1.15fr; }
  .swadhyay-grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 940px) {
  .donate-grid { grid-template-columns: 1.45fr 1fr; align-items: start; }
}
.section { padding-block: var(--section); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; top: 0; left: 50%; transform: translate(-50%, -110%);
  background: var(--ink); color: var(--paper); padding: .75rem 1.25rem;
  z-index: 200; text-decoration: none;
}
.skip-link:focus { transform: translate(-50%, 0); }

/* Eyebrow / section numeral — the editorial signature */
.eyebrow {
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: flex;
  align-items: baseline;
  gap: .75rem;
}
.eyebrow::before {
  content: attr(data-num);
  font-family: var(--display);
  font-variation-settings: 'opsz' 20;
  color: var(--gold-text);
  letter-spacing: 0;
}
.eyebrow--plain::before { content: none; }
/* One step up, for the kicker over the work-areas heading. */
.eyebrow--lg { font-size: var(--step--1); }

.lead { font-size: var(--step-1); line-height: 1.5; color: var(--ink-soft); }

/* Flame divider — the logo motif, abstracted to a rule */
.rule {
  border: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--line-strong), var(--line) 40%, transparent);
  margin-block: clamp(2rem, 5vw, 3.5rem);
}

/* ---------- Buttons ---------- */
.btn {
  --btn-bg: var(--ink);
  --btn-fg: var(--paper);
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding: .85em 1.6em;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--btn-bg);
  border-radius: var(--radius);
  transition: transform .3s var(--ease), background .3s var(--ease), color .3s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn .arw { transition: transform .3s var(--ease); }
.btn:hover .arw { transform: translateX(4px); }

.btn--gold { --btn-bg: var(--gold); --btn-fg: #2A1D05; }
.btn--gold:hover { --btn-bg: var(--gold-bright); }

.btn--ghost { --btn-bg: transparent; --btn-fg: var(--ink); border-color: var(--line-strong); }
.btn--ghost:hover { --btn-bg: var(--ink); --btn-fg: var(--paper); }
.btn--on-dark { --btn-bg: transparent; --btn-fg: var(--paper); border-color: rgba(250,246,239,.4); }
.btn--on-dark:hover { --btn-bg: var(--paper); --btn-fg: var(--ink); }

/* Text link with arrow */
.tlink {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--blue);
  border-bottom: 1px solid var(--line-strong);
  padding-bottom: .3rem;
  transition: border-color .3s var(--ease), color .3s var(--ease);
}
.tlink:hover { color: var(--gold-text); border-color: var(--gold-text); }
.tlink .arw { transition: transform .3s var(--ease); }
.tlink:hover .arw { transform: translateX(4px); }

/* =========================================================================
   Header
   ========================================================================= */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color .3s var(--ease), background .3s var(--ease);
}
.site-header.is-stuck { border-bottom-color: var(--line); }

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  /* Fixed bar height rather than padding around the crest, so the header stays
     put if the mark is resized again. 89 + the 1px border = 90. */
  min-height: 89px;
  padding-block: 0;
}
.brand { display: flex; align-items: center; gap: .7rem; text-decoration: none; min-width: 0; }
.brand img { width: 54px; height: 54px; flex-shrink: 0; }
@media (min-width: 600px) { .brand img { width: 82px; height: 82px; } }
.brand-text { line-height: 1.15; min-width: 0; }
.brand-name {
  display: block;
  font-family: var(--display);
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  font-variation-settings: 'opsz' 14;
  max-width: 11ch;
}
@media (min-width: 600px) {
  .brand-name { font-size: var(--step-0); font-variation-settings: 'opsz' 20; max-width: none; }
}
.brand-sub {
  display: none;
  font-size: var(--step--2);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
@media (min-width: 600px) { .brand-sub { display: block; } }

/* Compact the Donate button on small screens so the brand keeps its room */
@media (max-width: 599px) {
}

.nav { display: none; }
@media (min-width: 1024px) {
  .nav { display: flex; align-items: center; gap: 1.25rem; }
}
@media (min-width: 1240px) {
  .nav { gap: 2rem; }
}
/* Top-level labels must never wrap; the mega panel's own links still do. */
.nav > a, .nav-group > button { white-space: nowrap; }
.nav a {
  font-size: var(--step--1);
  font-weight: 500;
  text-decoration: none;
  padding-block: .35rem;
  border-bottom: 1px solid transparent;
  transition: border-color .25s var(--ease);
}
.nav a:hover, .nav a[aria-current="page"] { border-bottom-color: var(--gold); }

.nav-group { position: relative; }
.nav-group > button {
  display: inline-flex; align-items: center; gap: .35rem;
  background: none; border: 0; padding: .35rem 0;
  font-size: var(--step--1); font-weight: 500;
  border-bottom: 1px solid transparent;
}
.nav-group > button:hover { border-bottom-color: var(--gold); }
/* The panel opens at the header's bottom edge, leaving a gap the pointer has
   to cross on its way down. This bridges it so the group never loses hover. */
.nav-group > button { position: relative; }
.nav-group > button::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 1.6rem;
}
.nav-group > button svg { transition: transform .25s var(--ease); }
.nav-group[data-open="true"] > button svg { transform: rotate(180deg); }
.nav-menu {
  position: absolute;
  top: calc(100% + .9rem);
  left: -1.25rem;
  min-width: 300px;
  background: var(--paper);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lift);
  padding: .6rem;
  display: grid;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity .22s var(--ease), transform .22s var(--ease), visibility .22s;
}
.nav-group[data-open="true"] .nav-menu { opacity: 1; visibility: visible; transform: none; }
.nav-menu a {
  padding: .6rem 1rem;
  border-bottom: 0;
  border-left: 2px solid transparent;
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.nav-menu a:hover { background: var(--paper-warm); border-left-color: var(--gold); }
.nav-group > button[data-active="true"] { border-bottom-color: var(--gold); }

/* ---------- Mega menu ----------
   The panel is positioned against the sticky header, not the nav item, so it
   spans the full width and its columns share the page grid. */
.nav-group--mega { position: static; }
.nav-mega {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--paper);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-lift);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity .22s var(--ease), transform .22s var(--ease), visibility .22s;
}
.nav-group--mega[data-open="true"] .nav-mega { opacity: 1; visibility: visible; transform: none; }
/* Set just before following a link out of the panel — see site.js. */
.nav-group--mega[data-instant="true"] .nav-mega { transition: none; }
.nav-mega-inner { padding-block: 2.25rem 1.5rem; }
.nav-mega-cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2rem 3rem; }
.nav-col-head {
  margin: 0 0 .9rem;
  padding-bottom: .65rem;
  border-bottom: 1px solid var(--line);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.nav-col a {
  display: block;
  padding: .6rem .8rem;
  margin-inline: -.8rem;
  border-bottom: 0;
  border-left: 2px solid transparent;
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.nav-col a:hover, .nav-col a[aria-current="page"] { background: var(--paper-warm); border-left-color: var(--gold); }
/* A step up: the mega panel reads small next to the rest of the page. */
.nav-item-label { display: block; font-weight: 500; line-height: 1.35; font-size: var(--step-0); }
.nav-item-note {
  display: block;
  margin-top: .2rem;
  font-size: var(--step--1);
  font-weight: 400;
  line-height: 1.45;
  color: var(--ink-faint);
}
/* Same three-column rhythm as the panel above, so the standalone entries
   read as peers of the work areas rather than an afterthought. */
.nav-mega-foot {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem 3rem;
  margin-top: 1.85rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--line);
}
.nav-mega-foot a {
  display: block;
  padding: .5rem .8rem;
  margin-inline: -.8rem;
  border-bottom: 0;
  border-left: 2px solid transparent;
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.nav-mega-foot a:hover,
.nav-mega-foot a[aria-current="page"] { background: var(--paper-warm); border-left-color: var(--gold); }

.header-actions { display: flex; align-items: center; gap: .75rem; }
.menu-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  background: none; border: 1px solid var(--line-strong); border-radius: var(--radius);
}
/* Above 1024px the toggle is gone and the Donate button no longer sits here,
   so the wrapper is empty. Left in the flow it still counts as a flex item and
   space-between reserves a phantom third column, stranding the nav well short
   of the right edge — so take it out of the layout entirely. */
@media (min-width: 1024px) {
  .menu-toggle { display: none; }
  .header-actions { display: none; }
}
.menu-toggle span:not(.visually-hidden) { display: block; width: 18px; height: 1.5px; background: var(--ink); position: relative; transition: background .2s; }
.menu-toggle span:not(.visually-hidden)::before, .menu-toggle span:not(.visually-hidden)::after {
  content: ''; position: absolute; left: 0; width: 18px; height: 1.5px; background: var(--ink);
  transition: transform .3s var(--ease);
}
.menu-toggle span:not(.visually-hidden)::before { top: -6px; }
.menu-toggle span:not(.visually-hidden)::after { top: 6px; }
.menu-toggle[aria-expanded="true"] span:not(.visually-hidden) { background: transparent; }
.menu-toggle[aria-expanded="true"] span:not(.visually-hidden)::before { transform: translateY(6px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:not(.visually-hidden)::after { transform: translateY(-6px) rotate(-45deg); }

/* Mobile drawer */
.mobile-nav {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .35s var(--ease);
  border-top: 1px solid transparent;
}
.mobile-nav[data-open="true"] { grid-template-rows: 1fr; border-top-color: var(--line); }
/* Set just before following a link out of the drawer — see site.js. */
.mobile-nav[data-instant="true"] { transition: none; }
.mobile-nav > div { overflow: hidden; }
/* Open, the drawer becomes its own scroll container: capped to what is left
   below the header, and overscroll-behavior stops a flick at the end from
   handing the scroll to the page underneath. */
.mobile-nav[data-open="true"] > div {
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  max-height: calc(100dvh - 90px);
}
/* No overflow lock on the page here, deliberately. The header is
   position: sticky, and setting overflow: hidden on the root takes away the
   scroll container it sticks to — the header (and this drawer inside it) drops
   back to its static place at the top of the document, off-screen, while the
   page is frozen where it stood. That reads as the site hanging: no menu, no
   scroll. Containment is the scroller's job instead — see overscroll-behavior
   on .mobile-nav[data-open="true"] > div, which is what actually stops a flick
   inside the drawer from carrying on into the page. */
.mobile-nav ul { list-style: none; padding: 0; margin: 0; }
.mobile-nav a {
  display: block;
  padding: .95rem 0;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  font-size: var(--step-1);
  font-family: var(--display);
  font-variation-settings: 'opsz' 20;
}
.mobile-nav .sub a { padding-left: 1.25rem; font-family: var(--body); font-size: var(--step-0); color: var(--ink-soft); }
.mobile-nav .sub--break { margin-top: 1.4rem; }
.mobile-nav .grp span {
  display: block;
  padding: 1.1rem 0 .3rem;
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
@media (min-width: 1024px) { .mobile-nav { display: none; } }

/* =========================================================================
   Hero
   ========================================================================= */
.hero { position: relative; padding-block: clamp(2.5rem, 5vw, 4.5rem) clamp(2.5rem, 5vw, 4rem); }

.hero-grid {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
@media (min-width: 900px) {
  /* The portrait is the point of this hero, so it takes the larger share.
     740px is the cap because that is every real pixel the source has. */
  .hero-grid { grid-template-columns: minmax(0, 740px) minmax(400px, 1fr); }
}
/* The hero runs a little wider than the rest of the page to make room for it */
.hero .hero-grid { width: min(100% - (var(--gutter) * 2), 1400px); }

/* The hand-drawn portrait that opened the original site. Shown whole, on its
   own paper texture, never cropped. */
.hero-portrait {
  position: relative;
  justify-self: center;
  width: 100%;
  max-width: clamp(320px, 52vw, 740px);
}
/* No mask and no blend mode. The drawing's own background has been flattened
   and remapped to exactly this page's paper colour, so the edges of the image
   are already invisible. Masking it only produced a soft-edged smudge, and
   cutting it out on transparency erased his face — the pencil work is high-key,
   barely darker than the paper it sits on. */
.hero-portrait img { width: 100%; height: auto; }

.hero h1 { margin-top: 1.25rem; }

/* His words. Every quote is in the DOM; without JavaScript all three simply
   stack and read as a list, so nothing is ever hidden behind a script. */
.quotes { margin-top: clamp(1.75rem, 3vw, 2.5rem); }
.quotes-label {
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: .9rem;
}
.quotes-stage { display: grid; gap: 1rem; }
.quote blockquote {
  font-family: var(--display);
  font-style: italic;
  font-size: clamp(1.35rem, 2.5vw, 2.05rem);
  line-height: 1.34;
  color: var(--blue);
  font-variation-settings: 'SOFT' 40, 'opsz' 100;
  max-width: 30ch;
  min-height: 2.7em;
  position: relative;
  padding-left: 1.8rem;
}
.quote blockquote::before {
  content: '\201C';
  position: absolute;
  left: 0;
  top: -.12em;
  font-size: 2.4em;
  line-height: 1;
  color: var(--gold);
  opacity: .55;
}
.quotes-attrib {
  margin-top: 1rem;
  font-size: var(--step--1);
  letter-spacing: .06em;
  color: var(--ink-soft);
}
.quotes-attrib::before { content: '— '; }

.quotes-dots { display: flex; gap: .55rem; margin-top: 1.25rem; }
.quotes-dots button {
  width: 11px;
  height: 11px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: transparent;
  transition: background .3s var(--ease), border-color .3s var(--ease), transform .3s var(--ease);
}
.quotes-dots button:hover { border-color: var(--gold); transform: scale(1.15); }
.quotes-dots button[aria-selected="true"] { background: var(--blue); border-color: var(--blue); }
/* Only meaningful once JS can switch between them */
.quotes-dots { display: none; }
.js .quotes-dots { display: flex; }

/* With JS, one quote at a time */
.js .quotes-stage { display: grid; }
.js .quote { grid-area: 1 / 1; opacity: 0; visibility: hidden; }
.js .quote[data-active] { opacity: 1; visibility: visible; }

.hero-cta { display: flex; flex-wrap: wrap; gap: .9rem; margin-top: clamp(1.75rem, 3vw, 2.25rem); }

/* The Shantiniketan photograph, beneath the hero. Held to the page's content
   width rather than run edge to edge: the source is 1400px wide, so a
   full-bleed band was upscaling it on any large screen and softening it. */
.hero-band {
  width: min(100% - (var(--gutter) * 2), 1100px);
  margin-inline: auto;
}
.hero-band img {
  width: 100%;
  max-width: 1400px;   /* never scale past its own resolution */
  height: auto;
  object-fit: contain;
}
.hero-band .figcap { display: block; margin-top: .9rem; padding-bottom: clamp(2rem, 4vw, 3rem); }

/* Heading sitting directly above the band photograph, on its left edge. */
.hero-band-head { padding-top: clamp(2.5rem, 6vw, 4.5rem); }

/* A statement, not a photo credit: set to the full width of the band so it
   runs edge to edge beneath the photograph. */
.hero-statement {
  width: min(100% - (var(--gutter) * 2), 1100px);
  margin: clamp(1.5rem, 3vw, 2.25rem) auto 0;
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}
.hero-statement p {
  margin: 0;
  text-align: justify;
  text-wrap: pretty;
  font-size: var(--step-1);
  line-height: 1.7;
  color: var(--ink-soft);
}

.figcap {
  margin-top: .9rem;
  font-size: var(--step--2);
  line-height: 1.5;
  color: var(--ink-faint);
  letter-spacing: .02em;
  max-width: 44ch;
}

@property --hole {
  syntax: '<number>';
  inherits: true;
  initial-value: 1;
}

/* ---------- Page head with a photograph behind it ----------
   The scrim is heavy on purpose: the photographs are bright, busy group shots
   and three paragraphs of body copy sit on top of them. */
.hero-head {
  position: relative;
  isolation: isolate;
  color: var(--paper);
  /* Fills the screen below the sticky header. Grid rather than block so the
     copy can never overflow the box on a short window. */
  display: grid;
  align-content: start;
  min-height: calc(100svh - 5rem);
  padding-block: clamp(2.5rem, 6vw, 4.5rem);
  overflow: hidden;
}
.hero-head-art { position: absolute; inset: 0; z-index: -2; display: block; }
.hero-head-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;
}
/* Only ever seen through the spotlight, so this lifts the revealed area and
   nothing else. */
.hero-head-bg--colour { filter: brightness(1.24) saturate(1.55) contrast(1.05); }
/* The colour copy sits underneath. The grey copy on top is punched through by
   a soft circle that follows the pointer, so colour shows only where you look.
   Both <img> point at the same file, so this costs one download, not two. */
.hero-head-bg--gray {
  filter: grayscale(1) contrast(1.04);
  --mx: 50%;
  --my: 50%;
  -webkit-mask-image: radial-gradient(circle 340px at var(--mx) var(--my), rgba(0,0,0,var(--hole)) 0%, rgba(0,0,0,var(--hole)) 42%, #000 100%);
  mask-image: radial-gradient(circle 340px at var(--mx) var(--my), rgba(0,0,0,var(--hole)) 0%, rgba(0,0,0,var(--hole)) 42%, #000 100%);
  transition: --hole .4s var(--ease);
}
/* No pointer or reduced motion: the mask stays solid, so the photograph is
   simply black and white. */
@media (hover: none), (prefers-reduced-motion: reduce) {
  .hero-head-bg--gray { --hole: 1 !important; transition: none; }
}
.hero-head::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(100deg, rgba(15,18,26,.72) 0%, rgba(15,18,26,.64) 45%, rgba(15,18,26,.50) 100%);
}
.hero-head h1 {
  color: var(--paper);
  margin: 0 0 clamp(1.25rem, 3vw, 1.75rem);
  max-width: none;
}
.hero-head p {
  max-width: none;
  color: rgba(250, 246, 239, .88);
}
.hero-head p + p { margin-top: 1em; }

/* Page header for inner pages */
.page-head { padding-block: clamp(3rem, 7vw, 5.5rem) clamp(2rem, 4vw, 3rem); }
.page-head h1 { max-width: 18ch; margin-block: 1.25rem 1.5rem; }
.page-head .lead { max-width: 58ch; }

.breadcrumb { font-size: var(--step--2); color: var(--ink-faint); letter-spacing: .06em; text-transform: uppercase; }
.breadcrumb a { text-decoration: none; }
.breadcrumb a:hover { color: var(--gold); }
.breadcrumb span { margin-inline: .5rem; }

/* Full-bleed banner */
.banner { position: relative; overflow: hidden; }
/* A broader belt: the banner was shallow enough that the photograph read as
   a strip rather than a scene. */
/* Anchored to the top, not the centre. Banner photographs here are group
   portraits, and the one thing that must never be cut is the row of faces
   along the top. Anchoring that edge means the crop always takes from the
   floor instead — true at every window shape, including the wide-and-short
   ones where the 92vh cap makes the belt shallower than the picture. */
.banner img {
  width: 100%; height: clamp(420px, 50vw, 92vh);
  object-fit: cover; object-position: center top;
}
.banner::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(27,31,42,.18) 0%, rgba(27,31,42,.42) 45%, rgba(27,31,42,.72) 100%);
}
.banner-text {
  position: absolute; inset: auto 0 0 0; z-index: 2;
  padding-bottom: clamp(1.5rem, 4vw, 3rem);
  color: var(--paper);
}
/* Banner copy sits against the right edge of the page grid. */
.banner-text .wrap { display: flex; flex-direction: column; align-items: flex-end; text-align: right; }
.banner-text h1 { color: var(--paper); max-width: 30ch; }
.banner-text .eyebrow { color: rgba(250,246,239,.75); }

/* =========================================================================
   Impact figures — numbers as typography, not "stat cards"
   ========================================================================= */
.figures {
  background: var(--blue-deep);
  color: var(--paper);
  padding-block: clamp(3rem, 7vw, 5rem);
}
.figures-grid {
  display: grid;
  gap: clamp(2rem, 4vw, 2.5rem);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.figure-item { border-top: 1px solid rgba(250,246,239,.22); padding-top: 1.25rem; }
.figure-num {
  font-family: var(--display);
  font-size: var(--step-6);
  font-weight: 400;
  line-height: .95;
  letter-spacing: -0.03em;
  font-variation-settings: 'opsz' 144, 'SOFT' 40;
  color: var(--gold-bright);
  display: block;
}
.figure-num small { font-size: .5em; letter-spacing: 0; }
.figure-label { margin-top: .7rem; font-size: var(--step--1); line-height: 1.45; color: rgba(250,246,239,.82); }
.figures .eyebrow { color: rgba(250,246,239,.55); margin-bottom: 2.5rem; }
.figures .eyebrow::before { color: var(--gold-bright); }

/* =========================================================================
   Founder
   ========================================================================= */
.founder { background: var(--paper-warm); }
.founder-grid {
  display: grid;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
@media (min-width: 860px) { .founder-grid { grid-template-columns: 400px 1fr; } }
.founder-portrait { position: relative; }
.founder-portrait img {
  width: 100%;
  height: auto;
  object-fit: contain;
  filter: saturate(.92);
}
.founder-portrait::before {
  content: '';
  position: absolute; inset: -12px -12px 40px 40px;
  border: 1px solid var(--line-strong);
  z-index: -1;
}
/* The name is set to stay on one line under the portrait — at step-2 it
   broke after "Bhikhoobhai", leaving "Shah" stranded on its own. */
.founder-name {
  font-family: var(--display);
  font-size: min(var(--step-1), 5vw);
  margin-top: 1.1rem;
  white-space: nowrap;
}
/* Caption centred under the portrait — name and dates together. */
.founder-portrait figcaption { text-align: center; }
.founder-dates { font-size: var(--step--1); color: var(--ink-faint); letter-spacing: .1em; }
.founder blockquote {
  font-family: var(--display);
  font-size: var(--step-3);
  line-height: 1.28;
  letter-spacing: -0.018em;
  font-variation-settings: 'SOFT' 50, 'opsz' 100;
  margin-block: 1.5rem 2rem;
  padding-left: 1.5rem;
  border-left: 2px solid var(--gold);
}

/* =========================================================================
   Pillars — a stack of full cards that pin and layer over one another.
   Without scroll-driven animation they simply stack; nothing depends on it.
   ========================================================================= */
/* The three work areas, one numbered line each. Block, so each takes its own
   line without a <br>. The numerals are deliberately left to inherit the
   heading's colour rather than picking up an accent. */
.areas-head .area { display: block; }

.pillar-stack { display: grid; gap: clamp(1.25rem, 2.5vw, 2rem); overflow-x: clip; }

.pillar-card {
  position: relative;
  display: grid;
  overflow: hidden;
  border-radius: 4px;
  background: var(--paper-warm);
  box-shadow: 0 1px 2px rgba(27,31,42,.04), 0 24px 60px -32px rgba(27,31,42,.35);
}
@media (min-width: 900px) {
  .pillar-card { grid-template-columns: 1fr 1fr; min-height: min(62vh, 560px); }
}

.pillar-card[data-pillar="education"]   { --accent: var(--edu); }
.pillar-card[data-pillar="women"]       { --accent: var(--women); }
.pillar-card[data-pillar="seniors"]     { --accent: var(--seniors); }
.pillar-card[data-pillar="environment"] { --accent: var(--env); }

.pillar-media { position: relative; overflow: hidden; min-height: 220px; }
.pillar-media img {
  width: 100%;
  height: 100%;
  min-height: 220px;
  object-fit: cover;
  filter: saturate(.92);
}
.pillar-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 42%, color-mix(in srgb, var(--accent) 62%, transparent));
}

.pillar-body {
  padding: clamp(1.75rem, 3.5vw, 3rem);
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-self: center;
}
.pillar-index {
  font-family: var(--display);
  font-size: var(--step-1);
  color: var(--accent);
  letter-spacing: .02em;
}
.pillar-index span { color: var(--ink-faint); font-size: .7em; }
.pillar-card h3 { color: var(--accent); font-size: var(--step-3); }
.pillar-card blockquote {
  font-family: var(--display);
  font-size: var(--step-1);
  font-style: italic;
  line-height: 1.4;
  color: var(--ink-soft);
  padding-left: 1rem;
  border-left: 2px solid var(--accent);
}
.pillar-card ul { list-style: none; padding: 0; margin: 0; display: grid; gap: .5rem; }
.pillar-card li {
  font-size: var(--step--1);
  padding-left: 1.1rem;
  position: relative;
  color: var(--ink-soft);
}
.pillar-card li::before {
  content: '';
  position: absolute; left: 0; top: .62em;
  width: 5px; height: 5px;
  background: var(--accent);
  border-radius: 50%;
}
.pillar-projects { margin-top: .5rem; padding-top: 1.1rem; border-top: 1px solid var(--line); }
.pillar-projects .eyebrow { margin-bottom: .6rem; }
.pillar-projects a {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-size: var(--step--1);
  padding-block: .25rem;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color .25s var(--ease), border-color .25s var(--ease), gap .25s var(--ease);
}
.pillar-projects a + a { margin-left: 0; }
.pillar-projects a { display: flex; }
.pillar-projects a:hover { color: var(--accent); border-bottom-color: var(--accent); gap: .8rem; }

/* On a phone there is no hover to reveal that these are links, so they carry
   the colour and the rule at rest. */
@media (hover: none), (max-width: 767px) {
  .pillar-projects a { color: var(--accent); border-bottom-color: currentColor; }
  .pillar-projects a svg { opacity: 1; }
}
.pillar-projects a svg { opacity: .5; }
.pillar-none { font-size: var(--step--1); color: var(--ink-faint); }

/* =========================================================================
   Programme cards — editorial, asymmetric
   ========================================================================= */
.programmes { display: grid; gap: clamp(3rem, 6vw, 5rem); }
.programme {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
}
@media (min-width: 860px) {
  .programme { grid-template-columns: 1fr 1fr; }
  .programme:nth-child(even) .programme-figure { order: 2; }
}
.programme-figure { position: relative; }
.programme-figure img {
  width: 100%;
  /* 3:2 matches the source photographs, so almost nothing is cropped. These
     are group shots — the people at the edges are the point. */
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius);
}
.programme-tag {
  position: absolute;
  top: 1rem; left: 1rem;
  background: var(--paper);
  color: var(--accent, var(--ink));
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: .45rem .8rem;
}
.programme h3 { margin-bottom: .9rem; }
.programme h3 a { text-decoration: none; }
.programme h3 a:hover { color: var(--blue); }
.programme-fact {
  display: flex;
  width: fit-content;
  align-items: baseline;
  gap: .6rem;
  margin-block: 1.25rem;
  padding: .6rem 0;
  border-block: 1px solid var(--line);
  font-size: var(--step--1);
  color: var(--ink-soft);
}
.programme-fact b {
  font-family: var(--display);
  font-size: var(--step-2);
  font-weight: 500;
  color: var(--ink);
  font-variation-settings: 'opsz' 60;
}

/* =========================================================================
   Activity feed (Impact in Action)
   ========================================================================= */
.feed { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
@media (min-width: 700px)  { .feed { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1060px) { .feed { grid-template-columns: repeat(3, 1fr); } }
.feed-item {
  background: var(--paper);
  padding: clamp(1.5rem, 2.5vw, 2rem);
  display: flex;
  flex-direction: column;
  gap: .7rem;
  transition: background .3s var(--ease);
}
.feed-item:hover { background: var(--paper-warm); }
.feed-num {
  font-family: var(--display);
  font-size: var(--step-4);
  line-height: 1;
  font-weight: 400;
  color: var(--gold-text);
  font-variation-settings: 'opsz' 120, 'SOFT' 40;
}
.feed-item h3 { font-size: var(--step-1); }
.feed-item p { font-size: var(--step--1); color: var(--ink-soft); }

/* =========================================================================
   Trust band
   ========================================================================= */
.trust { background: var(--ink); color: var(--paper); }
.trust .eyebrow { color: rgba(250,246,239,.5); }
.trust .eyebrow::before { color: var(--gold-bright); }
.trust-grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  margin-top: 2.5rem;
}
@media (min-width: 800px) { .trust-grid { grid-template-columns: repeat(3, 1fr); } }
.trust-block h3 { font-size: var(--step-1); color: var(--gold-bright); margin-bottom: .9rem; }
.trust-block ul { list-style: none; padding: 0; margin: 0; display: grid; gap: .55rem; }
.trust-block li { font-size: var(--step--1); color: rgba(250,246,239,.78); line-height: 1.5; }
.trust-block li b { color: var(--paper); font-weight: 600; }

/* =========================================================================
   People (directors, advisory council)
   ========================================================================= */
.people {
  display: grid;
  gap: clamp(1.75rem, 3vw, 2.75rem);
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.person img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  object-position: top center;
  /* Greyscale at rest, colour under the pointer. */
  filter: grayscale(1);
  transition: filter .45s var(--ease);
  background: var(--paper-deep);
}
.person:hover img,
.person:focus-within img { filter: grayscale(0); }
@media (prefers-reduced-motion: reduce) {
  .person img, .council-portrait-img { transition: none; }
}
.person-name { font-family: var(--display); font-size: var(--step-1); margin-top: 1rem; }
.person-role {
  font-size: var(--step--2);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gold-text);
  margin-top: .3rem;
}
.person p { font-size: var(--step--1); color: var(--ink-soft); margin-top: .75rem; line-height: 1.55; }

.council { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
@media (min-width: 640px)  { .council { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .council { grid-template-columns: repeat(3, 1fr); } }
.council-item { background: var(--paper); padding: clamp(1.25rem, 2.5vw, 1.75rem); }
.council-portrait {
  display: block;
  width: clamp(132px, 12vw, 176px);
  height: clamp(132px, 12vw, 176px);
  border-radius: 50%;
  overflow: hidden;
  margin-bottom: 1.15rem;
  background: var(--paper-deep);
}
.council-portrait-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  /* Barely any zoom now — the 1.08 scale was cropping the picture a second
     time and lifting it off centre. */
  transform: scale(1.02);
  filter: grayscale(1);
  transition: filter .45s var(--ease);
}
.council-item:hover .council-portrait-img,
.council-item:focus-within .council-portrait-img { filter: grayscale(0); }
.council-item h3 { font-size: var(--step-1); }
.council-item p { font-size: var(--step--1); color: var(--ink-soft); margin-top: .5rem; line-height: 1.5; }

/* =========================================================================
   Timeline
   ========================================================================= */
.timeline { list-style: none; padding: 0; margin: 0; position: relative; }
.timeline::before {
  content: '';
  position: absolute;
  left: 0; top: .5rem; bottom: .5rem;
  width: 1px;
  background: var(--line-strong);
}
.timeline li { position: relative; padding-left: clamp(2rem, 5vw, 3.5rem); padding-bottom: 2.25rem; }
.timeline li:last-child { padding-bottom: 0; }
.timeline li::before {
  content: '';
  position: absolute;
  left: -4px; top: .55em;
  width: 9px; height: 9px;
  background: var(--gold);
  border: 2px solid var(--paper);
  border-radius: 50%;
}
.timeline-year {
  font-family: var(--display);
  font-size: var(--step-2);
  font-weight: 500;
  color: var(--blue);
  font-variation-settings: 'opsz' 60;
  display: block;
  margin-bottom: .35rem;
}
.timeline p { color: var(--ink-soft); max-width: 56ch; }

/* =========================================================================
   Offer / feature grid
   ========================================================================= */
.offers { display: grid; gap: clamp(1.5rem, 3vw, 2.25rem); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.offer { border-top: 2px solid var(--line-strong); padding-top: 1.25rem; }
.offer h3 { font-size: var(--step-1); margin-bottom: .6rem; }
.offer p { font-size: var(--step--1); color: var(--ink-soft); }

/* ---------- Support this work ----------
   A full-bleed band rather than a boxed panel, so it reads as a section of
   the page and carries its own vertical room. */
.donate-band {
  background: var(--paper-warm);
  padding-block: clamp(3.5rem, 8vw, 6rem);
}
.donate-band .eyebrow { margin-bottom: 1.25rem; }
.donate-band .lead { margin: 0 0 2rem; }
.donate-band-note {
  margin: 1.5rem 0 0;
  font-size: var(--step--2);
  color: var(--ink-faint);
}

/* ---------- An Initiative by UB Heritage ----------
   Mirrors the band on the current site: mark, line, address — centred on a
   solid field, in the palette's navy rather than the old brand blue. */
.ub-band {
  background: var(--paper-warm);
  color: var(--ink);
  padding-block: clamp(3.5rem, 8vw, 5.5rem);
  text-align: center;
}
/* The mark is dark artwork on transparency, and the band is warm paper, so it
   sits directly on the background with nothing behind it. */
.ub-band-logo {
  width: clamp(220px, 26vw, 320px);
  height: auto;
  margin-inline: auto;
  display: block;
}
.ub-band h2 {
  color: var(--ink);
  margin-block: clamp(1.5rem, 3vw, 2rem) .75rem;
  max-width: none;
}
.ub-band a {
  color: var(--gold-text);
  font-size: var(--step-0);
  letter-spacing: .02em;
  text-decoration-color: rgba(142, 99, 27, .45);
  text-underline-offset: .3em;
}
.ub-band a:hover { color: var(--ink); text-decoration-color: var(--gold); }

/* ---------- Mission / vision / commitment, over a photograph ----------
   The source image already carries a dark gradient on its left, so the scrim
   only has to even that out and hold the right-hand side. */
/* A deeper belt: at the old height only 58% of the photograph's height
   survived the crop, because the band was 3:1 and the picture is 16:9. */
.mission-band { position: relative; isolation: isolate; overflow: hidden; padding-block: clamp(6rem, 15vw, 13rem); }
.mission-band-bg {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  /* Barely any zoom now — the 1.08 scale was cropping the picture a second
     time and lifting it off centre. */
  transform: scale(1.02);
}
.mission-band::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgba(12, 15, 22, .86) 0%, rgba(12, 15, 22, .82) 50%, rgba(12, 15, 22, .78) 100%);
}
/* No rules above the headings here, and the copy inverts to sit on the photo.
   Set a step larger than the offer cards elsewhere: this copy carries the
   Foundation's mission and has a whole band to itself. */
.mission-band .offer { border-top: 0; padding-top: 0; }
.mission-band .offer h3 { color: var(--paper); font-size: var(--step-2); }
.mission-band .offer p { color: rgba(250, 246, 239, .88); font-size: var(--step-0); line-height: 1.6; }

/* =========================================================================
   Gallery
   ========================================================================= */
.gallery {
  display: grid;
  gap: clamp(.75rem, 1.5vw, 1.1rem);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 230px), 1fr));
}
.gallery img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius);
  transition: transform .5s var(--ease), filter .5s var(--ease);
  filter: saturate(.95);
}
.gallery a { display: block; overflow: hidden; border-radius: var(--radius); }
.gallery a:hover img { transform: scale(1.04); filter: saturate(1.05); }

/* =========================================================================
   Stories
   ========================================================================= */
.stories { display: grid; gap: clamp(2rem, 4vw, 3rem); grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.story { display: flex; flex-direction: column; }
.story img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; border-radius: var(--radius); }
.story .eyebrow { margin-top: 1.1rem; }
.story h3 { margin-block: .6rem .7rem; font-size: var(--step-2); }
.story h3 a { text-decoration: none; }
.story h3 a:hover { color: var(--blue); }
.story p { font-size: var(--step--1); color: var(--ink-soft); }

.article { max-width: 68ch; margin-inline: auto; }
.article h2 { font-size: var(--step-3); margin-block: 2.5rem 1rem; }
.article h3 { font-size: var(--step-2); margin-block: 2rem .75rem; }
.article p { margin-bottom: 1.15em; }
.article > p:first-of-type { font-size: var(--step-1); line-height: 1.55; color: var(--ink-soft); }
.article figure { margin-block: 2.5rem; }
.article figure img { width: 100%; border-radius: var(--radius); }
.article blockquote {
  font-family: var(--display);
  font-size: var(--step-2);
  line-height: 1.35;
  border-left: 2px solid var(--gold);
  padding-left: 1.5rem;
  margin-block: 2rem;
  color: var(--ink);
}

/* =========================================================================
   Forms
   ========================================================================= */
.form-grid { display: grid; gap: 1.25rem; }
@media (min-width: 640px) { .form-grid--2 { grid-template-columns: repeat(2, 1fr); } }
.field { display: grid; gap: .45rem; }
.field label { font-size: var(--step--1); font-weight: 600; letter-spacing: .02em; }
.field .hint { font-size: var(--step--2); color: var(--ink-faint); }
.field input, .field select, .field textarea {
  width: 100%;
  padding: .8rem .9rem;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px var(--blue-tint);
}
.field textarea { min-height: 130px; resize: vertical; }
.field-full { grid-column: 1 / -1; }

.tabs { display: flex; gap: .5rem; border-bottom: 1px solid var(--line); margin-bottom: 2.5rem; flex-wrap: wrap; }
.tab {
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: .8rem 1.1rem;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: -1px;
  transition: color .25s var(--ease), border-color .25s var(--ease);
}
.tab[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--gold); }
.tabpanel[hidden] { display: none; }

/* Donation amount chooser */

/* Info / bank details panel */
.panel {
  background: var(--paper-warm);
  border: 1px solid var(--line);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  border-radius: var(--radius);
}
.panel h3 { font-size: var(--step-1); margin-bottom: 1rem; }
.dl { display: grid; gap: .6rem; margin: 0; }
@media (min-width: 520px) { .dl { grid-template-columns: max-content 1fr; column-gap: 1.5rem; } }
.dl dt { font-size: var(--step--2); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); }
.dl dd { margin: 0; font-size: var(--step-0); }

/* Gap flag — marks content the foundation must supply */
.gap {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  background: repeating-linear-gradient(45deg, var(--gold-tint), var(--gold-tint) 6px, #F9F0DC 6px, #F9F0DC 12px);
  border: 1px dashed var(--gold);
  color: #6B4A08;
  font-family: var(--body);
  font-size: .72em;
  font-weight: 600;
  letter-spacing: .04em;
  padding: .1em .5em;
  border-radius: var(--radius);
  vertical-align: middle;
  text-transform: none;
}

/* =========================================================================
   CTA band
   ========================================================================= */
.cta {
  background: var(--blue-deep);
  color: var(--paper);
  position: relative;
  overflow: hidden;
}
.cta::before {
  content: '';
  position: absolute;
  top: -30%; right: -10%;
  width: 55vw; height: 160%;
  background: radial-gradient(ellipse at center, rgba(227,169,60,.16), transparent 62%);
  pointer-events: none;
}
.cta-inner { position: relative; display: grid; gap: 2rem; align-items: center; }
@media (min-width: 880px) { .cta-inner { grid-template-columns: 1.25fr 1fr; } }
.cta h2 { color: var(--paper); max-width: 16ch; }
.cta p { color: rgba(250,246,239,.8); margin-top: 1rem; max-width: 48ch; }
.cta-actions { display: flex; flex-wrap: wrap; gap: .9rem; }
@media (min-width: 880px) { .cta-actions { justify-content: flex-end; } }

/* Three ways to help */
.ways { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
@media (min-width: 760px) { .ways { grid-template-columns: repeat(3, 1fr); } }
.way {
  background: var(--paper);
  padding: clamp(1.75rem, 3vw, 2.5rem);
  display: flex;
  flex-direction: column;
  gap: .8rem;
  text-decoration: none;
  transition: background .3s var(--ease);
}
.way:hover { background: var(--paper-warm); }
.way h3 { font-size: var(--step-2); }
.way p { font-size: var(--step--1); color: var(--ink-soft); flex: 1; }
.way .tlink { align-self: flex-start; margin-top: .5rem; }

/* =========================================================================
   Footer
   ========================================================================= */
.site-footer {
  background: var(--ink);
  color: var(--paper);
  padding-block: clamp(3rem, 6vw, 4.5rem) 2rem;
}
.footer-grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3rem);
}
@media (min-width: 700px)  { .footer-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .footer-grid { grid-template-columns: 1.05fr 1.5fr .8fr 1.15fr; } }
.site-footer nav a { white-space: nowrap; }
.site-footer h2 {
  font-size: var(--step--2);
  font-family: var(--body);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--gold-bright);
  margin-bottom: 1.1rem;
}
.site-footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: .6rem; }
.site-footer a { color: rgba(250,246,239,.82); text-decoration: none; font-size: var(--step--1); transition: color .2s var(--ease); }
.site-footer a:hover { color: var(--gold-bright); text-decoration: underline; text-underline-offset: .25em; }
.footer-brand img { width: 62px; height: 62px; margin-bottom: 1rem; }
.footer-brand p { font-size: var(--step--1); color: rgba(250,246,239,.72); max-width: 34ch; }
.footer-contact li { font-size: var(--step--1); color: rgba(250,246,239,.82); line-height: 1.55; }
.socials { display: flex; gap: .75rem; margin-top: 1.25rem; }
.socials a {
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  border: 1px solid rgba(250,246,239,.28);
  border-radius: 50%;
  transition: background .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease);
}
.socials a:hover { background: var(--gold-bright); border-color: var(--gold-bright); color: var(--ink); }
.footer-bottom {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: 1.5rem;
  border-top: 1px solid rgba(250,246,239,.16);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.75rem;
  justify-content: space-between;
  align-items: center;
  font-size: var(--step--2);
  color: rgba(250,246,239,.62);
}
.footer-bottom nav { display: flex; flex-wrap: wrap; gap: 1.25rem; }
.footer-bottom a { font-size: var(--step--2); }




/* =========================================================================
   Latest updates rail
   A native horizontal scroller with scroll-snap. It is fully usable by touch,
   trackpad, keyboard and scrollbar with no JavaScript at all — the arrow
   buttons are an enhancement and stay hidden until JS unhides them.
   ========================================================================= */
/* Paper, not paper-warm: the UB Heritage band directly above is warm, and
   two warm bands running together read as one long block. */
.social { background: var(--paper); }
.social-head {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  align-items: end;
  margin-bottom: clamp(2rem, 4vw, 2.75rem);
}
@media (min-width: 900px) { .social-head { grid-template-columns: 1fr auto; } }
.social-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }
.social-actions .btn { gap: .55rem; }
.social-actions .btn svg { flex: none; }

.rail-nav { display: flex; gap: .5rem; }
.rail-nav button {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: var(--paper);
  transition: background .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease);
}
.rail-nav button:hover:not(:disabled) { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.rail-nav button:disabled { opacity: .35; cursor: default; }

.rail {
  list-style: none;
  margin: 0;
  padding: 0 0 1.25rem;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(240px, 300px);
  gap: clamp(1rem, 2vw, 1.5rem);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
}
.rail > * { scroll-snap-align: start; }
.rail:focus-visible { outline: 2px solid var(--blue); outline-offset: 6px; }

.post {
  display: grid;
  gap: .7rem;
  height: 100%;
  align-content: start;
  text-decoration: none;
  color: inherit;
}
.post-media { display: block; overflow: hidden; border-radius: var(--radius); background: var(--paper-deep); }
.post-media img {
  width: 100%;
  /* Reels are 9:16 and posts are square; 4:5 shows a fair amount of both
     without cropping the vertical ones to a letterbox. */
  aspect-ratio: 4 / 5;
  object-fit: cover;
  transition: transform .5s var(--ease);
}
.post:hover .post-media img { transform: scale(1.05); }
.post-theme em {
  font-style: normal;
  color: var(--ink-faint);
  font-weight: 500;
}
.post-theme {
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gold-text);
}
.post-caption { font-size: var(--step--1); line-height: 1.5; color: var(--ink); }
.post-link {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  margin-top: auto;
  font-size: var(--step--2);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  transition: color .25s var(--ease);
}
.post-link svg { width: 14px; height: 14px; }
.post:hover .post-link { color: var(--blue); }

.social-note {
  margin-top: 1.5rem;
  font-size: var(--step--2);
  color: var(--ink-faint);
  max-width: 70ch;
}

/* =========================================================================
   Ribbon — a band of the programme names. Static without motion.css.
   ========================================================================= */
.ribbon {
  background: var(--ink);
  color: var(--paper);
  overflow: hidden;
  padding-block: clamp(.9rem, 1.6vw, 1.35rem);
  border-block: 1px solid rgba(250,246,239,.12);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.ribbon-track { display: flex; width: max-content; will-change: transform; }
.ribbon-track > span {
  display: inline-flex;
  align-items: center;
  gap: clamp(1.5rem, 3vw, 2.75rem);
  padding-right: clamp(1.5rem, 3vw, 2.75rem);
  font-family: var(--display);
  font-size: var(--step-2);
  white-space: nowrap;
  color: rgba(250,246,239,.62);
}
.ribbon-track b { font-weight: 500; color: var(--gold-bright); }
.ribbon-track i { font-style: normal; color: rgba(250,246,239,.28); }
/* The names link to their pages. Underline only on hover/focus so the resting
   band still reads as a band rather than a list of links. */
.ribbon-track a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color .18s var(--ease), color .18s var(--ease);
}
.ribbon-track a:hover { color: var(--paper); border-bottom-color: currentColor; }
.ribbon-track a:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 4px;
  border-radius: 2px;
}

/* =========================================================================
   Story articles — a drop cap to open
   ========================================================================= */
.article > p:first-of-type::first-letter {
  font-family: var(--display);
  font-size: 3.4em;
  line-height: .82;
  font-weight: 500;
  float: left;
  padding: .06em .1em 0 0;
  color: var(--blue);
  font-variation-settings: 'opsz' 144, 'SOFT' 40;
}

/* Cursor elements exist in the DOM but are invisible until motion.js
   confirms a fine pointer, so touch devices never see them. */

/* =========================================================================
   Cinematic sections — STRUCTURE ONLY.
   The animation for all of this lives in motion.css, which is optional.
   Everything below must look correct and be fully readable without it.
   ========================================================================= */

/* Scroll progress rail (motion.css fills it; without it, it stays invisible) */
.progress { position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 150; transform: scaleX(0); transform-origin: 0 50%; pointer-events: none; }

.hero-grid { position: relative; z-index: 1; }

.scroll-cue {
  position: absolute;
  bottom: 1.5rem;
  left: 50%;
  translate: -50% 0;
  display: grid;
  justify-items: center;
  gap: .6rem;
  font-size: var(--step--2);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--ink-faint);
  pointer-events: none;
}
.scroll-cue i { display: block; width: 1px; height: 42px; background: linear-gradient(180deg, var(--line-strong), transparent); position: relative; overflow: hidden; }
@media (max-width: 899px) { .scroll-cue { display: none; } }

/* Per-word spans. Without motion.css these are simply inline words. */
.w { display: inline-block; }

/* The tribute — the dark band on the homepage */
.tribute {
  position: relative;
  background: var(--ink);
  color: var(--paper);
  overflow: hidden;
  padding-block: clamp(4rem, 10vw, 9rem);
}
.tribute::before {
  content: '';
  position: absolute;
  inset: -20% -10% auto auto;
  width: 60vw;
  height: 130%;
  background: radial-gradient(ellipse at 70% 40%, rgba(227,169,60,.13), transparent 60%);
  pointer-events: none;
}
.tribute-inner { position: relative; display: grid; gap: clamp(2.5rem, 6vw, 5rem); align-items: center; }
@media (min-width: 900px) { .tribute-inner { grid-template-columns: 380px 1fr; } }

.tribute-portrait { position: relative; }
.tribute-portrait img {
  width: 100%;
  height: auto;
  object-fit: contain;
  filter: saturate(.86) contrast(1.04);
}
.tribute .eyebrow { color: rgba(250,246,239,.55); }
.tribute .eyebrow::before { color: var(--gold-bright); }
/* Tribute copy runs the full width of its column, justified. */
.tribute-body {
  max-width: none;
  text-align: justify;
  text-wrap: pretty;
  color: rgba(250, 246, 239, .78);
}
.tribute-name { font-family: var(--display); font-size: var(--step-2); margin-top: 1.25rem; }
.tribute-dates { font-size: var(--step--1); letter-spacing: .1em; color: rgba(250,246,239,.55); }

/* The quote. Fully legible by default — motion.css dims it and lights it back
   up on scroll, so losing that file leaves the text readable, not invisible. */
.lit {
  font-family: var(--display);
  font-size: clamp(1.5rem, 3.1vw, 2.6rem);
  line-height: 1.32;
  letter-spacing: -0.018em;
  font-variation-settings: 'SOFT' 50, 'opsz' 100;
  margin-block: 1.75rem 2.5rem;
  padding-left: clamp(1rem, 2vw, 1.75rem);
  border-left: 2px solid var(--gold);
  color: rgba(250,246,239,.97);
}

/* =========================================================================
   Motion — one orchestrated reveal, honoured opt-out
   ========================================================================= */
/* Only hide when JS is confirmed running. Without JS, nothing is ever hidden. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
  transition-delay: var(--d, 0ms);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .js [data-reveal] { opacity: 1; transform: none; }
}

/* ---------- Print ---------- */
@media print {
  body::before, .site-header, .cta, .site-footer { display: none; }
  body { background: #fff; color: #000; }
}

/* Programme name and tagline on a work-area card */
.pillar-tagline {
  font-family: var(--display);
  font-size: var(--step-1);
  font-style: italic;
  color: var(--accent);
  margin-top: -.35rem;
}

/* Honeypot: off-screen rather than display:none, which some bots detect. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Shown only when a submission came back with a problem. */
.form-note {
  margin: 0 0 1.5rem;
  padding: 1rem 1.25rem;
  border-left: 3px solid var(--gold);
  background: rgba(0, 0, 0, .04);
  font-size: var(--step--1);
}

/* The arithmetic check. Appears only once a question has been fetched. */
.captcha[hidden] { display: none; }
.captcha b { font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.captcha input { max-width: 10rem; }

/* Inline validation. The message sits with its field, not in a summary
   somewhere else on the page. */
.field-error {
  display: block;
  margin-top: .4rem;
  font-size: var(--step--2);
  color: #a3341f;
}
.field.has-error input,
.field.has-error textarea,
.field.has-error select { border-color: #a3341f; }

/* The submit button is only gated once JavaScript is running; without it the
   button stays usable and the server does the checking. */
.btn[disabled] { opacity: .5; cursor: not-allowed; }

.form-note--error { border-left-color: #a3341f; }

/* A successful donation: the details are saved and payment is opening. */
.form-note--sent { border-left-color: #2f6f4f; }
.form-note--sent a { color: inherit; }

/* =========================================================================
   Image viewer
   ========================================================================= */
.viewer-open { overflow: hidden; }          /* the page must not scroll behind */

.viewer {
  position: fixed;
  inset: 0;
  /* Above the sticky header (100) and the skip link (200). The grain overlay
     sits higher still, but it has pointer-events:none and is only texture. */
  z-index: 300;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: clamp(.5rem, 2vw, 1.5rem);
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(16, 19, 27, .975);
  animation: viewer-in .18s var(--ease) both;
}
.viewer[hidden] { display: none; }

@keyframes viewer-in { from { opacity: 0 } to { opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .viewer { animation: none; } }

.viewer-stage {
  margin: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}
.viewer-stage img {
  max-width: 100%;
  /* room for the caption underneath, whatever the viewport */
  max-height: calc(100dvh - 10rem);
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, .04);
}
.viewer-stage figcaption {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: .75rem;
  max-width: 62ch;
  text-align: center;
  font-size: var(--step--1);
  line-height: 1.5;
  color: rgba(250, 246, 239, .88);
}
.viewer-count {
  font-size: var(--step--2);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(250, 246, 239, .55);
  white-space: nowrap;
}

.viewer-nav,
.viewer-close {
  display: grid;
  place-items: center;
  border: 1px solid rgba(250, 246, 239, .22);
  background: rgba(250, 246, 239, .06);
  color: var(--paper);
  border-radius: 50%;
  cursor: pointer;
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.viewer-nav { width: 3rem; height: 3rem; }
.viewer-nav[hidden] { display: none; }
.viewer-nav:hover,
.viewer-close:hover { background: rgba(250, 246, 239, .16); border-color: var(--gold); }
.viewer-nav:focus-visible,
.viewer-close:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: 3px; }

.viewer-close {
  position: absolute;
  top: clamp(.75rem, 2vw, 1.5rem);
  right: clamp(.75rem, 2vw, 1.5rem);
  width: 2.75rem;
  height: 2.75rem;
  font-size: 1.6rem;
  line-height: 1;
}

/* On a phone the arrows sit under the picture rather than squeezing it. */
@media (max-width: 640px) {
  .viewer {
    grid-template-columns: 1fr;
    grid-template-areas: 'stage' 'nav';
    align-content: center;
    justify-items: center;
  }
  .viewer-stage { grid-area: stage; }
  .viewer-nav--prev { grid-area: nav; justify-self: start; }
  .viewer-nav--next { grid-area: nav; justify-self: end; }
  .viewer-stage img { max-height: calc(100dvh - 14rem); }
}

/* River Farm sections alternate: even cards photo-left, odd cards photo-right.
   Desktop only — every card stacks photo-above-text on a phone. */
@media (min-width: 860px) {
  .two-col > .rf-figure.flip { order: 2; }
}

/* Section photographs share one shape, so a pair of stacked sections reads as
   a set rather than two unrelated blocks. Cover, so nothing is squashed. */
.section-figure img { aspect-ratio: 4 / 3; object-fit: cover; width: 100%; }

@media (min-width: 860px) {
  .two-col > .section-figure.flip { order: 2; }
}
