/* ============================================================================
   CHES — v2 page-level layouts
   ========================================================================= */

/* ---------- section head: eyebrow + heading + lede, with optional side slot -- */

.head { max-width: 720px; }
.head--wide { max-width: 900px; }
.head--split {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: end;
  max-width: none;
}
@media (max-width: 880px) { .head--split { grid-template-columns: 1fr; align-items: start; } }
.head__aside { padding-bottom: 0.4rem; }
.head__aside p { margin-bottom: 0; }

/* ---------- editorial split: text one side, image the other ---------- */

/* Gutter cut from 5.5rem to 3rem. Two columns separated by 88px of nothing on a
   wide screen is not breathing room, it is a hole — and it was starving both
   sides at once: the text column was cramped AND the photograph beside it was
   small, because the gap was eating the width they should have shared. */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.6rem, 3.4vw, 3rem);
  align-items: center;
}
.split--wide-left  { grid-template-columns: 1.15fr 1fr; }
.split--wide-right { grid-template-columns: 1fr 1.15fr; }

/* A column holding nothing but a heading does not need half the page. These
   were the biggest empty areas on the site — "What happens next." sat alone in
   a 50% column with roughly 600px of white beneath it. The heading gets only
   the width it needs to set on two lines; the content takes the rest. */
.split:has(> div > h2:only-child) {
  grid-template-columns: minmax(12rem, 0.6fr) 1.6fr;
  align-items: start;
}
@media (max-width: 900px) {
  .split, .split--wide-left, .split--wide-right { grid-template-columns: 1fr; }
  /* :has() carries higher specificity than a plain class, so the unconditional
     rule above (line 39) was winning at every width, phone included — the
     heading stayed stuck in a narrow column instead of stacking full-width.
     Repeating the selector here, inside the media query, gives this rule equal
     specificity to that one; CSS then breaks the tie by source order, and being
     later in the file, this wins below 900px. Confirmed from a live screenshot:
     "What happens next." stuck at ~35% width next to a squeezed numbered list. */
  .split:has(> div > h2:only-child) { grid-template-columns: 1fr; }
}
/* align-self:start matters. Without it the figure is stretched to match the
   text column beside it, the image is dragged from its own 1.43:1 shape into
   a tall box, and object-fit crops the sides off — the "looks like you cropped
   an image and pasted it in" problem. Height stays derived from the picture. */
.split__media { position: relative; border-radius: var(--radius); overflow: hidden; margin: 0; align-self: start; }
.split__media img { width: 100%; height: auto; aspect-ratio: var(--photo-ratio); object-fit: cover; }

/* Carousel variant. The first slide keeps its place in normal flow so the frame
   still derives its height from a real image; the rest are absolutely
   positioned on top of it. That way the box can never collapse, even if a
   later slide is slow to decode. */
.split__media[data-slides] img { transition: opacity 1.2s var(--ease-soft); }
.split__media[data-slides] img:not(:first-child) {
  position: absolute;
  inset: 0;
  height: 100%;
  opacity: 0;
}
.split__media[data-slides] img:first-child { opacity: 0; }
.split__media[data-slides] img.is-active { opacity: 1; }
.no-js .split__media[data-slides] img:first-child { opacity: 1; }

/* ---------- media stack: photograph with a fact plate locked beneath it ------
   The plate used to float on a negative margin, which left it hanging off the
   photo at an arbitrary offset and reading as misaligned at every width.
   Stacking them in a grid instead means the two share one edge and one width
   at every breakpoint, with nothing to drift. */

.media-stack { display: grid; grid-template-rows: auto auto; align-self: start; }
.media-stack .split__media { border-radius: var(--radius) var(--radius) 0 0; }

.plate {
  background: var(--ink);
  color: var(--ground);
  padding: 1.4rem 1.5rem;
  border-radius: 0 0 var(--radius) var(--radius);
  display: flex;
  align-items: baseline;
  gap: 1.1rem;
}
.plate__figure {
  font-family: var(--font-display);
  font-size: 2.4rem;
  font-weight: 600;
  line-height: 1;
  color: var(--brand-lit);
  flex-shrink: 0;
}
.plate p { color: color-mix(in srgb, var(--ground) 76%, var(--ink)); font-size: 0.88rem; margin: 0; }
@media (max-width: 420px) {
  .plate { flex-direction: column; align-items: flex-start; gap: 0.5rem; }
}

/* ---------- timeline ---------- */

.timeline { position: relative; padding-left: 2.2rem; margin: 0; }
.timeline::before {
  content: "";
  position: absolute;
  left: 5px; top: 8px; bottom: 8px;
  width: 1px;
  background: var(--border-firm);
}
/* Brass fill that draws downward as the block reveals. */
.timeline::after {
  content: "";
  position: absolute;
  left: 5px; top: 8px;
  width: 1px;
  background: var(--brand);
  height: 0;
  transition: height 1.6s var(--ease-soft) 0.2s;
}
.timeline.is-visible::after { height: calc(100% - 16px); }

.timeline__item { position: relative; padding-bottom: 2rem; }
.timeline__item:last-child { padding-bottom: 0; }
.timeline__item::before {
  content: "";
  position: absolute;
  left: -2.2rem;
  top: 7px;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--ground);
  border: 2px solid var(--brand);
  transform: scale(0);
  transition: transform 0.5s var(--ease-soft);
  transition-delay: calc(var(--i, 0) * 180ms + 400ms);
}
.timeline.is-visible .timeline__item::before { transform: scale(1); }
/* No text-transform. The markup already reads "1990s – 2000s" correctly, and
   uppercasing it rendered "1990S – 2000S" — the decade suffix is always
   lowercase, so the styling was introducing a typographic error the content
   never had. Tracking eased from 0.14em to 0.08em because that much letter
   spacing exists to open up all-caps; on mixed case it just looks loose. */
.timeline__year {
  display: block;
  font-family: var(--font-body);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--brand-ink);
  margin-bottom: 0.35rem;
}
.timeline__item h3 { font-size: 1.1rem; margin-bottom: 0.3rem; }
.timeline__item p { margin-bottom: 0; font-size: 0.95rem; }

/* ---------- sticky scroll: pinned heading beside scrolling content ---------- */

/* Narrower pin column and a tighter gutter. The heading only needs enough width
   to set on two lines; giving it a full 1fr left a tall empty channel down the
   left of the whole timeline, which is the white space under "Four decades,
   one job." */
.sticky-wrap {
  display: grid;
  grid-template-columns: minmax(14rem, 0.72fr) 1.6fr;
  gap: clamp(1.6rem, 4vw, 3.4rem);
  align-items: start;
}
@media (max-width: 900px) { .sticky-wrap { grid-template-columns: 1fr; } }
.sticky-wrap__pin { position: sticky; top: 120px; }
@media (max-width: 900px) { .sticky-wrap__pin { position: static; } }
.sticky-wrap__flow > * + * { margin-top: 1.3rem; }

/* ---------- value list: numbered rows that fill on hover ---------- */

/* Three columns, not two. Each row was a number plus a single stacked block of
   heading-over-paragraph, and the paragraph is capped at a readable measure —
   so every row ran out of content around halfway and left the right-hand half
   of the section empty down the whole page. Splitting the heading into its own
   column lets the paragraph start further right and finish at the true edge:
   same content, no wasted half, and the rows read denser. */
.values { list-style: none; padding: 0; margin: 0; border-top: 1px solid var(--border); }
.values li {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(9rem, 15rem) 1fr;
  gap: clamp(1rem, 3vw, 2.4rem);
  align-items: baseline;
  padding: clamp(1.4rem, 2.6vw, 2rem) 0;
  border-bottom: 1px solid var(--border);
  margin: 0;
  transition: padding-left 0.45s var(--ease);
}
/* The row's inner wrapper holds h3 + p; unwrap it so both become grid cells. */
.values li > div { display: contents; }
.values li h3 { margin: 0; align-self: baseline; }
.values li p  { margin: 0; max-width: 62ch; }

@media (max-width: 780px) {
  .values li { grid-template-columns: auto 1fr; }
  .values li > div { display: block; }
  .values li h3 { margin-bottom: 0.35rem; }
}
.values li:hover { padding-left: 0.9rem; }
.values li::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--brand);
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform 0.45s var(--ease);
}
.values li:hover::before { transform: scaleY(1); }
.values__num {
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--brand-ink);
  padding-top: 0.35rem;
}
.values h3 { margin-bottom: 0.35rem; }
.values p { margin-bottom: 0; max-width: 62ch; }

/* ---------- page head ---------- */

.page-head {
  background: var(--ink);
  padding-block: clamp(4rem, 9vw, 7.5rem) clamp(3rem, 6vw, 5rem);
  position: relative;
  overflow: hidden;
}
.page-head h1 { color: var(--ground); max-width: 18ch; }
.page-head p { color: color-mix(in srgb, var(--ground) 76%, var(--ink)); max-width: 56ch; font-size: clamp(1rem, 1.3vw, 1.15rem); }
.page-head .eyebrow { color: var(--brand-lit); }
.page-head .eyebrow::before { background: var(--brand-lit); }
.breadcrumb { font-size: 0.8rem; color: color-mix(in srgb, var(--ground) 58%, var(--ink)); margin-bottom: 1.4rem; }
.breadcrumb a { color: color-mix(in srgb, var(--ground) 78%, var(--ink)); }
.breadcrumb a:hover { color: var(--brand-lit); }

/* ---------- gallery ---------- */

.gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
@media (max-width: 900px) { .gallery { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .gallery { grid-template-columns: 1fr; } }

/* ---------- horizontal photo strip ---------- */

/* ---------- photographs: grid, not a scrolling rail ----------
   This was a horizontal flex rail. Flex stretches every item to the height of
   the tallest one, so each landscape photograph was being forced into a tall
   portrait box and `object-fit: cover` then sliced the sides off — which is
   why the painted Hindi banners, the most valuable thing in these pictures,
   were cut in half in every single frame.

   A grid fixes it at the root: each cell derives its height from the image's
   own 912×638 ratio, so nothing stretches and nothing crops. It also shows all
   the photographs at once instead of hiding two thirds of them behind arrows
   nobody clicks. Spans alternate so the wall has rhythm rather than reading as
   another uniform card row. */
.strip__viewport { overflow: visible; }
.strip__rail {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(0.7rem, 1.4vw, 1.1rem);
  padding-bottom: 0;
}
.strip__rail > *      { grid-column: span 2; }
.strip__rail > :nth-child(1),
.strip__rail > :nth-child(2) { grid-column: span 3; }

/* Exactly four photographs (the homepage grid) tile as a clean 2×2 instead of
   leaving a two-column hole on the second row. */
.strip__rail > :nth-child(1):nth-last-child(4),
.strip__rail > :nth-child(1):nth-last-child(4) ~ * { grid-column: span 3; }

@media (max-width: 900px) {
  .strip__rail { grid-template-columns: repeat(2, 1fr); }
  .strip__rail > *,
  .strip__rail > :nth-child(1),
  .strip__rail > :nth-child(2) { grid-column: span 1; }
}
@media (max-width: 560px) {
  .strip__rail { grid-template-columns: 1fr; }
}

/* The arrows steered a scroll container that no longer exists. Declared last so
   nothing below can turn them back on — the previous pass left the old
   `display:flex` further down the file, which quietly re-showed them. */
.strip__nav { display: none !important; }

/* Nothing may stretch a photograph. A grid item defaults to stretching to its
   row's height, and once the box is taller than the picture's own 1.43:1 shape
   `object-fit: cover` silently crops the sides — which is what was still
   slicing the bottom row. Pinning align-self and height:auto removes every
   path by which the box can end up taller than the image inside it. */
.strip__rail { align-items: start; }
.photo-card { align-self: start; }
.photo-card img { height: auto; }

/* ---------- CTA band ---------- */

.cta {
  background: var(--ink);
  border-radius: var(--radius);
  padding: clamp(2.4rem, 5.5vw, 4.5rem);
  display: grid;
  grid-template-columns: 1.5fr auto;
  gap: clamp(1.8rem, 4vw, 3.5rem);
  align-items: center;
  position: relative;
  overflow: hidden;
}
@media (max-width: 880px) { .cta { grid-template-columns: 1fr; } }
.cta h2 { color: var(--ground); margin-bottom: 0.6rem; }
.cta h2 .accent { color: var(--brand-lit); }
.cta p { color: color-mix(in srgb, var(--ground) 78%, var(--ink)); margin-bottom: 0; max-width: 54ch; }
.cta__actions { display: flex; gap: 0.8rem; flex-wrap: wrap; }

/* ---------- programme detail rows ---------- */

/* Fully opaque — same fix as .site-header. This bar sticks directly over
   scrolling programme copy; any transparency at all means text bleeds through
   whenever the backdrop blur fails to render. */
/* top:62px, matching the header's CONDENSED height — not its resting 78px.
   This bar is not transparent and never was: the background is solid. The bug
   was a 16px gap. The header shrinks from 78px to 62px once you scroll, but
   this bar stayed pinned at 78px, so a 16px band opened between the two and
   page content scrolled through it — reading exactly like a see-through bar.
   Pinning to the condensed height closes it. While the header is still at its
   full 78px this bar tucks behind it instead (header z-index 100 beats this
   bar's 60), which is invisible rather than broken. */
.prog-nav {
  position: sticky;
  top: 62px;
  z-index: 60;
  background: var(--ground);
  border-bottom: 1px solid var(--border);
}

/* Clicking a tab jumped the section to the very top of the viewport, where the
   sticky header and this bar — about 120px of chrome between them — covered the
   section heading and the first line of its intro. The visitor arrived at a
   section whose title they could not see. scroll-margin-top reserves that space
   so the heading lands just below the bar. */
/* Programmes carries a SECOND sticky bar under the header, so its anchors need
   more clearance than the site-wide scroll-padding reserves. This stacks on top
   of it. */
.section:has(.prog-item),
.prog-item { scroll-margin-top: 66px; }
.prog-nav .container { display: flex; gap: 0.3rem; overflow-x: auto; scrollbar-width: none; }
.prog-nav .container::-webkit-scrollbar { display: none; }
.prog-nav a {
  padding: 1rem 0.9rem;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.prog-nav a:hover, .prog-nav a.is-active { color: var(--ink); border-bottom-color: var(--brand); text-decoration: none; }

/* ---------- programme catalogue ----------
   Was a stack of full-width text rows: heading, paragraph, metadata list,
   horizontal rule, repeat — 753 words and one image on the entire page, which
   is a document rather than a page you browse. A visitor deciding what to fund
   has to read it linearly to find out what is even on offer.

   So each programme becomes a catalogue entry with a cover, the way a menu or a
   product listing works: picture, name, one line, and the specifics underneath.
   You can scan twelve of them in the time the old page took to read one.

   Cards are usually the lazy default, but a catalogue of comparable items is
   precisely the case where they are the honest structure. */

/* The container already holds the heading, the lede and then the programmes, so
   it becomes the grid itself rather than wrapping the cards in a new element —
   the heading and lede simply span every column. Keeps the markup untouched. */
/* align-items:start, NOT stretch — this was the blank space.
   Stretching every card to the tallest in its row, with the spec strip pinned
   to the bottom, opened a dead white gap in the middle of every card whose
   description ran short. Twelve cards, three per row, and the shortest one in
   each row set the size of everyone else's hole. Cards now take the height
   their content needs; rows end slightly ragged, which is what every product
   grid does and is far better than a page of voids. */
/* THREE FIXED COLUMNS, and the section heading is a cell in the grid rather
   than a full-width banner above it. That was the real empty space: the
   heading claimed an entire row and used a third of it, then a two-card
   section left another whole column blank beside the cards. Right-hand third
   of the page, empty, on every section.

   With the heading occupying a cell, the counts come out exact:
     Training  = head(1) + 2 cards = 3  -> one full row
     Health    = head(2) + 4 cards = 6  -> two full rows
     Awareness = head(2) + 4 cards = 6  -> two full rows
     Education = head(1) + 2 cards = 3  -> one full row
   Nothing is left over anywhere. auto-fill is deliberately NOT used here: it
   creates however many columns happen to fit and reintroduces the orphan. */
/* TWO columns, not three. The section card counts are 2, 4, 4, 2 — every one
   divisible by two — so a two-column grid can never leave an orphan or an
   empty cell, at any width, without any per-section special-casing.

   Three columns forced the heading into a card-sized cell to absorb the
   leftover, and that traded a horizontal hole for a vertical one: the heading
   cell is short, the card beside it is tall, and the grid row takes the height
   of the tallest thing in it. The heading is now its own compact full-width
   row instead, and the cards below it always land in complete rows. */
.section:has(.prog-item) > .container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1rem, 2vw, 1.5rem);
  align-items: start;
}

/* Heading and its intro sit side by side across the full width, so the header
   is one short band rather than a tall stack with empty space beside it. */
.prog-head {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: clamp(1rem, 2.5vw, 2.2rem);
  align-items: end;
  margin-bottom: clamp(0.4rem, 1.5vw, 1rem);
}
.prog-head h2 { margin: 0; }
.prog-head .lede { margin-bottom: 0; font-size: 1rem; max-width: none; }

@media (max-width: 820px) {
  .section:has(.prog-item) > .container { grid-template-columns: 1fr; }
  .prog-head { grid-template-columns: 1fr; align-items: start; }
  .prog-head h2 { margin-bottom: 0.6rem; }
}

@media (max-width: 1000px) {
  .section:has(.prog-item) > .container { grid-template-columns: repeat(2, 1fr); }
  #health-medical > .container > .prog-head,
  #awareness-empowerment > .container > .prog-head,
  .prog-head { grid-column: 1 / -1; align-self: start; }
}
@media (max-width: 620px) {
  .section:has(.prog-item) > .container { grid-template-columns: 1fr; }
}

/* This page is four stacked sections; the standard section padding put roughly
   180px of nothing between each one. */
.section:has(.prog-item) { padding-block: clamp(2.4rem, 4vw, 3.6rem); }
.section:has(.prog-item) > .container > h2,
.section:has(.prog-item) > .container > .lede { grid-column: 1 / -1; }
.section:has(.prog-item) > .container > .lede { margin-bottom: clamp(0.6rem, 1.5vw, 1.2rem); }

.prog-item {
  display: flex;
  flex-direction: column;
  background: var(--raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  padding: 0;
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease),
              transform 0.3s var(--ease);
}
.prog-item:hover {
  border-color: var(--border-firm);
  box-shadow: var(--shadow);
  transform: translateY(-2px);
}

.prog-item__media { margin: 0; overflow: hidden; background: var(--ground-warm); }
.prog-item__media img {
  width: 100%;
  height: auto;
  aspect-ratio: var(--photo-ratio);
  object-fit: cover;
  transition: transform 0.7s var(--ease-soft);
}
.prog-item:hover .prog-item__media img { transform: scale(1.04); }

/* No flex:1. The text block used to grow to fill the stretched card, which is
   precisely what created the internal gap. It now takes only the room it needs
   and the spec strip follows immediately underneath. */
.prog-item > div {
  padding: clamp(1rem, 1.8vw, 1.25rem) clamp(1rem, 1.8vw, 1.25rem) 0;
}
.prog-item h3 { margin: 0 0 0.4rem; }
.prog-item > div > p { margin-bottom: 0; font-size: 0.93rem; line-height: 1.55; }

/* Every catalogue entry needs a way to act on it. These cards were dead ends —
   a visitor who found the exact programme they wanted had to scroll to the
   bottom of the page to do anything about it. The link carries the programme
   name into the enquiry so the founders know what was clicked. */
.prog-item__act {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0.85rem clamp(1rem, 1.8vw, 1.25rem) 0;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--brand-ink);
}
.prog-item__act span { transition: transform 0.3s var(--ease); display: inline-block; }
.prog-item:hover .prog-item__act span { transform: translateX(3px); }
/* Sits at the foot of the card as a spec strip on its own tinted ground, so the
   description reads as prose and the specifics read as data. margin-top:auto
   pins it to the bottom regardless of how long the description runs. */
.prog-meta {
  list-style: none;
  margin: clamp(1rem, 2vw, 1.3rem) 0 0;
  padding: 0.9rem clamp(1.1rem, 2vw, 1.4rem);
  display: grid;
  gap: 0;
  background: var(--ground-warm);
  border-top: 1px solid var(--border);
}
.prog-meta li {
  display: grid;
  grid-template-columns: 6.6rem 1fr;
  gap: 0.8rem;
  margin: 0;
  padding: 0.42rem 0;
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 7%, transparent);
  font-size: 0.82rem;
  line-height: 1.45;
}
.prog-meta li:last-child { border-bottom: 0; }
.prog-meta b {
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--neutral-ink);
  padding-top: 0.15rem;
}
.prog-meta span { color: var(--muted); }
@media (max-width: 520px) { .prog-meta li { grid-template-columns: 1fr; gap: 0.2rem; } }

/* ---------- credentials ---------- */

.cred-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.2rem; }
@media (max-width: 760px) { .cred-grid { grid-template-columns: 1fr; } }
.cred {
  background: var(--raised);
  border: 1px solid var(--border);
  border-left: 2px solid var(--brand);
  border-radius: var(--radius);
  padding: 1.4rem 1.5rem;
}
.cred h3 {
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--neutral-ink);
  margin-bottom: 0.55rem;
}
.cred__value {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 0.4rem;
  word-break: break-word;
}
.cred p:last-child { margin-bottom: 0; font-size: 0.88rem; }

.doc-figure { margin: 0; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--raised); }
.doc-figure figcaption { padding: 1rem 1.2rem; font-size: 0.85rem; color: var(--muted); border-top: 1px solid var(--border); }

/* ---------- trust badges ---------- */

.badges { display: flex; gap: 0.8rem; flex-wrap: wrap; margin-top: 2rem; }
.badge {
  border: 1px solid var(--border-firm);
  border-radius: var(--radius);
  padding: 0.85rem 1.1rem;
  min-width: 116px;
}
.badge__figure {
  display: block;
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1;
  margin-bottom: 0.3rem;
}
.badge__label { display: block; font-size: 0.7rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--neutral-ink); }

/* ---------- enquiry panel ---------- */

.enquiry { background: var(--raised); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.enquiry__head { padding: 1.6rem 1.7rem 1.2rem; border-bottom: 1px solid var(--border); }
.enquiry__head h3 { margin-bottom: 0.3rem; }
.enquiry__head p { margin: 0; font-size: 0.9rem; }
.enquiry__body { padding: 1.7rem; }

.compliance {
  margin-top: 1.6rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--border);
  font-size: 0.83rem;
  color: var(--neutral-ink);
}
.compliance p { margin: 0; font-size: 0.83rem; color: var(--neutral-ink); }

/* ---------- support / donate ---------- */

.support-box { background: color-mix(in srgb, var(--ground) 10%, transparent); border: 1px solid color-mix(in srgb, var(--ground) 18%, transparent); border-radius: var(--radius); padding: 1.7rem; }
.support-box h3 { color: var(--ground); }
.support-box dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 0.5rem 1.2rem; }
.support-box dt { font-size: 0.7rem; letter-spacing: 0.11em; text-transform: uppercase; color: color-mix(in srgb, var(--ground) 56%, var(--ink)); padding-top: 0.15rem; }
.support-box dd { margin: 0; color: var(--ground); font-size: 0.93rem; }

/* ---------- profile (print) page ---------- */

.profile-doc { max-width: 820px; }
.profile-row { display: grid; grid-template-columns: 200px 1fr; gap: 1.2rem; padding: 0.7rem 0; border-bottom: 1px solid var(--border); font-size: 0.94rem; }
.profile-row b { font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--neutral-ink); }
@media (max-width: 620px) { .profile-row { grid-template-columns: 1fr; gap: 0.2rem; } }

@media print {
  .profile-row { break-inside: avoid; }
  .section { padding-block: 0; }
  a { color: var(--ink); }
}

/* ---------- promo prompt ---------- */

.promo-overlay {
  position: fixed;
  inset: 0;
  z-index: 400;
  background: color-mix(in srgb, #0b0b0a 62%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  opacity: 0;
  transition: opacity 0.4s var(--ease);
}
.promo-overlay[hidden] { display: none; }
.promo-overlay.is-open { opacity: 1; }
.promo {
  background: var(--raised);
  border-radius: var(--radius);
  padding: 2.2rem;
  max-width: 420px;
  position: relative;
  transform: translateY(14px) scale(0.98);
  transition: transform 0.5s var(--ease-soft);
}
.promo-overlay.is-open .promo { transform: none; }
.promo h4 { font-family: var(--font-display); font-size: 1.45rem; margin-bottom: 0.6rem; }
.promo__close {
  position: absolute;
  top: 0.7rem; right: 0.7rem;
  width: 34px; height: 34px;
  border: 0; background: transparent;
  color: var(--muted);
  font-size: 1.4rem;
  cursor: pointer;
  line-height: 1;
}
.promo__close:hover { color: var(--ink); }

/* ============================================================================
   PHONE PASS
   The display scale, the two-column splits and the hover-only affordances all
   need explicit handling below 720px rather than relying on clamp() alone.
   ========================================================================= */

@media (max-width: 720px) {
  /* clamp()'s vw term keeps headings large on a phone in landscape and on
     tablets; cap the top of the scale outright so a five-word headline can't
     eat the whole screen. */
  h1 { font-size: clamp(2.1rem, 9vw, 2.9rem); }
  h2 { font-size: clamp(1.75rem, 7vw, 2.3rem); }

  /* svh, not vh — this is the phone breakpoint, where the difference is the
     whole point: vh ignores the browser's address bar and toolbar, so the hero
     renders taller than the visible screen.

     Height also drops from 78 to 62. This is not a taste change: the hero photo
     is landscape (1500x1050) inside a tall narrow phone viewport, and
     object-fit:cover scales to fill the HEIGHT, so the taller the box the more
     is sliced off the sides. At 78svh roughly 550px of a 944px-wide render was
     being cropped away, which cut the painted Hindi banner off at both edges —
     the banner being the single most persuasive thing in the photograph.
     Shorter box, less horizontal loss, banner readable. */
  .hero { min-height: 62vh; min-height: 62svh; }
  .hero h1 { max-width: 100%; }
  .hero__lede { font-size: 1rem; }
  .hero__actions { width: 100%; }
  .hero__actions .btn { flex: 1 1 auto; justify-content: center; }

  /* Stat grid: two up rather than four squashed. */
  .stats { grid-template-columns: repeat(2, 1fr); }
  .stat { padding: 1.6rem 0.9rem; }
  .stat__figure { font-size: clamp(1.9rem, 8vw, 2.4rem); }
  .stat__label { font-size: 0.7rem; letter-spacing: 0.07em; }

  /* Head splits stack, so the aside no longer needs bottom alignment. */
  .head--split { gap: 1.2rem; }
  .head__aside { padding-bottom: 0; }

  /* Numbered rows: the number sits above the text instead of beside it, which
     stops the heading being squeezed into a narrow column. */
  .values li { grid-template-columns: 1fr; gap: 0.4rem; padding: 1.3rem 0; }
  .values li:hover { padding-left: 0; }
  .values__num { padding-top: 0; }

  .timeline { padding-left: 1.7rem; }
  .timeline__item::before { left: -1.7rem; }

  .plate { padding: 1.2rem 1.2rem; }
  .plate__figure { font-size: 2rem; }

  .cta { padding: 1.8rem 1.4rem; }
  .cta__actions { width: 100%; }
  .cta__actions .btn { flex: 1 1 auto; justify-content: center; }

  .feature--tall, .feature--tall .feature__body,
  .feature, .feature__body { min-height: 300px; }

  .prog-nav { top: 62px; }
  .prog-nav a { padding: 0.85rem 0.7rem; font-size: 0.8rem; }

  .badges { gap: 0.5rem; }
  .badge { min-width: 0; flex: 1 1 30%; padding: 0.7rem 0.8rem; }
  .badge__figure { font-size: 1.1rem; }

  .enquiry__head, .enquiry__body { padding: 1.2rem; }

  .accordion summary { font-size: 1rem; padding-right: 2.4rem; }

  .footer__bottom .container { flex-direction: column; gap: 0.3rem; }
}

/* Touch devices have no hover, so effects that only exist on hover are dead
   weight. Give the equivalent affordance permanently instead.

   On desktop the rail and its padding-left both arrive together, only on
   hover, so there's never a moment where the line shows without room reserved
   for it. Here the rail was made permanently visible but the matching padding
   was left behind — the line sat flush at left:0 with the text starting
   immediately beside it, no gap at all. Confirmed from a live phone screenshot. */
@media (hover: none) {
  .values li::before { transform: scaleY(1); }
  .values li { padding-left: 0.9rem; }
  .card:hover { transform: none; box-shadow: var(--shadow); }
  a.card::before { transform: scaleX(1); }
  .link-arrow::after { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
  .timeline::after { height: calc(100% - 16px); transition: none; }
  .timeline__item::before { transform: scale(1); transition: none; }
  .values li:hover { padding-left: 0; }
  .promo { transform: none; }
}
