
@font-face{font-family:'Bricolage Grotesque';font-weight:800;font-display:swap;src:url(/assets/bricolage-800.woff2) format('woff2')}
@font-face{font-family:'Bricolage Grotesque';font-weight:600;font-display:swap;src:url(/assets/bricolage-600.woff2) format('woff2')}
@font-face{font-family:'Hanken Grotesk';font-weight:400;font-display:swap;src:url(/assets/hanken-400.woff2) format('woff2')}
@font-face{font-family:'Hanken Grotesk';font-weight:600;font-display:swap;src:url(/assets/hanken-600.woff2) format('woff2')}
@font-face{font-family:'Hanken Grotesk';font-weight:800;font-display:swap;src:url(/assets/hanken-800.woff2) format('woff2')}
@font-face{font-family:'Spline Sans Mono';font-weight:500;font-display:swap;src:url(/assets/splinemono-500.woff2) format('woff2')}

:root{
  /* Android Chrome runs "Auto Dark Theme" on any page that does not say what
     schemes it supports: it rewrites the colours itself and this light design
     comes back near black, with the gradient headline unreadable. The keyword
     that stops it is "only", which forbids the browser overriding us; a bare
     "light" merely declares support and is still auto darkened. Alorah has one
     palette and no dark variant, so this is the honest declaration. */
  color-scheme: only light;
  --paper:#FDFDFB; --mist:#F5F5F9; --card:#FFFFFF;
  --ink:#12162E; --slate:#575D75;
  --lapis:#2438A0; --lapis-deep:#16204F; --lapis-soft:#E9ECFB;
  --copper:#B97C34; --copper-deep:#96652A; --copper-soft:#F7EEDF;
  /* The same copper and green, one notch darker, for SMALL text printed on
     their own tinted panel, where the brand values read 4.35 and 4.41 and the
     body floor is 4.5. Everywhere else the brand values stand: a 44px display
     letter is LARGE text and clears a 3:1 floor with room to spare. Mirrors
     copperOnSoft and okOnSoft in the apps' theme.js. */
  --copper-on-soft:#8E5F27; --ok-on-soft:#187245;
  --hair:#E7E6EF; --hair-2:#D9D8E6;
  --ok:#1B7F4D;
  --disp:'Bricolage Grotesque','Hanken Grotesk',system-ui,sans-serif;
  --body:'Hanken Grotesk',system-ui,sans-serif;
  /* THE FIGURE FACE: MONEY AND CODES. Added 2026-08-30, and it takes both of
     those away from the mono face for a measured reason.

     Owner, 2026-08-30, on the amount chips: "Align these neatly. should we
     remove the bold because the dot inside 0 is causing confusion." The bold
     came off that morning and the chips went to mono 500, which answered the
     weight but not either of the two things he was actually looking at. Both
     were measured in headless Chrome afterwards, at the sizes really used:

       - THE COMMA TAKES A WHOLE CELL. In a monospaced face every glyph has one
         advance, so the comma in a grouped figure sits alone with a digit's
         worth of air either side: "1.00 of a digit" against 0.43 in the body
         face. That is why the chips looked ragged and why the admin app printed
         a total he read as two numbers, "28 , 553".
       - O AND 0 ARE THE SAME SHAPE. Only 13% of their ink differs in Spline
         Sans Mono 500, against 62.6% in Hanken Grotesk 600. He read the
         donation code ALO/26-27/0011 as "AL0". The stakes are not only tidiness:
         the same face prints the trust's IFSC, UTIB0004995, and its account
         number, which a donor copies by eye into a bank transfer.

     So money, codes, references and registration numbers are set in the BODY
     face with tabular figures, which is what the admin console's tables have
     always done. Tabular numerals are what actually makes a column line up; the
     typewriter look never was.

     ALWAYS WITH font-variant-numeric BESIDE IT: the `font:` shorthand resets
     font-variant, so a rule that sets `font:` and forgets this line silently
     loses its tabular figures. */
  --fig:'Hanken Grotesk',system-ui,sans-serif;
  /* THE MONO FACE IS NOW FOR A DATE AND A COUNTER, NEVER FOR PROSE,
     AND NEVER FOR MONEY OR A CODE, WHICH IS WHAT --fig IS FOR.
     Owner, 2026-08-29, comparing the site with the app: "App seems to be so
     beautiful while the web is worst." Six places had drifted into setting
     whole sentences in it, and the donate form's fine print was mono AND
     text-align:justify, which on a 360px phone gave eight words a line and
     rivers of white between them. The app prints the same sentence in the body
     face, left aligned, and that is what a person reads.
     A date and a counter stay mono. A code, an amount, a reference and a
     registration number moved to --fig on 2026-08-30, with the measurements
     above. */
  --mono:'Spline Sans Mono',ui-monospace,monospace;
  --maxw:1180px; --r:18px; --r-s:10px;
  --ease:cubic-bezier(.22,.61,.36,1);
  --shadow:0 1px 2px rgba(18,22,46,.05),0 12px 32px -12px rgba(18,22,46,.12);
  --shadow-lift:0 2px 4px rgba(18,22,46,.06),0 24px 48px -16px rgba(18,22,46,.18);
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:88px}
body{font-family:var(--body);font-size:16.5px;line-height:1.65;color:var(--ink);background:var(--paper)}
img{max-width:100%;display:block}
h1,h2,h3{font-family:var(--disp);font-weight:800;line-height:1.06;letter-spacing:-.015em;text-wrap:balance}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px}
.eyebrow{display:inline-flex;align-items:center;gap:8px;font:800 12.5px/1 var(--body);letter-spacing:.16em;text-transform:uppercase;color:var(--lapis)}
.eyebrow::before{content:"";width:22px;height:2px;background:linear-gradient(90deg,var(--copper),var(--lapis))}
.skip{position:absolute;left:-9999px;top:0;background:var(--lapis);color:#fff;padding:10px 18px;z-index:99;font-weight:800;border-radius:0 0 10px 0}
.skip:focus{left:0;top:0}
:focus-visible{outline:2px solid var(--lapis);outline-offset:2px}

/* ---------- nav ---------- */
.nav{position:fixed;inset:0 0 auto 0;z-index:50;transition:.3s var(--ease)}
.nav.scrolled{background:rgba(253,253,251,.82);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 1px 0 var(--hair)}
.nav-in{max-width:var(--maxw);margin:0 auto;padding:12px 24px;display:flex;align-items:center;gap:28px}
.brand{display:flex;align-items:center;gap:11px;text-decoration:none;color:var(--ink)}
.brand img{width:42px;height:42px}
.brand b{font-family:var(--disp);font-weight:800;font-size:19px;letter-spacing:-.01em}
.brand small{display:block;font:800 9px/1 var(--body);letter-spacing:.28em;text-transform:uppercase;color:var(--copper-deep);margin-top:2px}
.nav-links{display:flex;gap:4px;margin-left:auto;align-items:center}
.nav-links a{font:600 14px/1 var(--body);color:var(--ink);text-decoration:none;padding:10px 14px;border-radius:999px;transition:background .2s}
.nav-links a:hover{background:var(--mist)}
/* Get Help: the same shape as Donate, in outline. Two filled buttons side by
   side would compete, and a plain text link lost to a green WhatsApp bubble for
   three weeks. */
.nav-help{border:1.5px solid var(--ink);font-weight:800!important;padding:9.5px 18px!important}
/* .nav-links a:hover sets a light background and is MORE specific than a bare
   .nav-help:hover, so the pill stayed pale while the text went white and the
   words disappeared. Owner caught it in a screenshot on 2026-08-29. Matching
   the specificity is the fix; !important on a colour would have hidden the
   next one of these. */
.nav-links a.nav-help:hover,.nav-links a.nav-help:focus-visible,
.mobile-menu a.nav-help:hover,.mobile-menu a.nav-help:focus-visible,
a.nav-help-m:hover,a.nav-help-m:focus-visible{background:var(--ink);color:#fff}
.nav-help-m{display:none}
.nav-cta{background:var(--ink);color:#fff!important;font-weight:800!important;padding:11px 20px!important}
.nav-cta:hover{background:var(--lapis)!important}
.menu-btn{display:none;margin-left:auto;flex:none;background:var(--card);border:1px solid var(--hair);width:44px;height:44px;border-radius:12px;font-size:19px;cursor:pointer;color:var(--ink)}
/* THE MENU IS A SCROLLING SHEET THAT HAPPENS TO BE CENTRED.
   justify-content:center on a column that overflows puts the first item ABOVE
   the top of the box, where no scroll can reach it: the owner photographed
   "Our Name" cut in half on 2026-08-29. Two zero-height pseudo items with auto
   margins centre the block while there is free space and collapse to nothing
   when there is not, so a menu taller than the phone scrolls from the top. */
.mobile-menu{position:fixed;inset:0;background:rgba(253,253,251,.97);backdrop-filter:blur(10px);z-index:49;display:none;flex-direction:column;gap:2px;padding:84px 24px 28px;text-align:center;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
.mobile-menu.open{display:flex}
.mobile-menu::before,.mobile-menu::after{content:"";flex:none;margin:auto}
/* 28px display type made every row 70px tall, so eight of them were taller than
   the phone they had to fit in. 20px still reads as the display face and still
   leaves a 45px target. */
.mobile-menu a{font-family:var(--disp);font-weight:600;font-size:20px;line-height:1.3;color:var(--ink);text-decoration:none;padding:11px 12px;border-radius:12px}
.mobile-menu a:hover{background:var(--mist)}
/* Get Help and Donate close the menu as a PAIR: one width, one type size, one
   outline and one filled. Get Help ran the full width of the sheet in display
   type while Donate sat small and centred underneath, and the two read as
   unrelated things. */
.mobile-menu a.nav-help{font-family:var(--body);font-size:15.5px;padding:13px 20px!important;margin:18px auto 0;border-radius:999px;width:100%;max-width:260px;justify-content:center}
.mobile-menu .nav-cta{font-family:var(--body);font-size:15.5px;padding:13px 20px!important;margin:10px auto 0;border-radius:999px;width:100%;max-width:260px}

/* ---------- hero ---------- */
.hero{position:relative;padding:150px 0 72px;overflow:hidden}
.hero-bg{position:absolute;inset:0;pointer-events:none;background:
  radial-gradient(560px 420px at 82% 30%,rgba(36,56,160,.10),transparent 65%),
  radial-gradient(640px 480px at 74% 62%,rgba(185,124,52,.14),transparent 65%)}
.hero-grid{position:relative;display:grid;grid-template-columns:1.15fr .85fr;gap:48px;align-items:center}
.hero-badge{display:inline-flex;align-items:center;gap:9px;background:var(--card);border:1px solid var(--hair);border-radius:999px;padding:8px 16px 8px 10px;font:600 14px/1.4 var(--body);color:var(--slate);box-shadow:var(--shadow);margin-bottom:28px}
.hero-badge .dot{width:8px;height:8px;border-radius:50%;background:var(--ok);box-shadow:0 0 0 4px rgba(27,127,77,.15)}
.hero-badge b{color:var(--ink)}
.hero-badge .bi{white-space:nowrap}
/* The separator is its own element so a phone can drop it. Inline it is a
   space saver; stacked it is an orphan, and "· Serving across India" opening a
   line is what the owner photographed on 2026-08-29. */
/* No pale colour on it: it is text, and the contrast sweep measured the one I
   first gave it at 1.41:1. It inherits, and the spacing around it does the
   separating. */
.hero-badge .sep{font-style:normal}
.hero h1{font-size:clamp(44px,6.6vw,86px);margin-bottom:24px;max-width:14ch}
.hero h1 .glow{background:linear-gradient(92deg,var(--copper) 10%,var(--lapis) 90%);-webkit-background-clip:text;background-clip:text;color:transparent}
.hero .lede{font-size:19px;color:var(--slate);max-width:50ch;margin-bottom:34px}
.cta-row{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:44px}
/* The `hidden` attribute only carries `display:none` from the browser's own
   stylesheet, so ANY class here that sets a display beats it and the element
   stays on screen. `.btn` and `.fgrid` both do. Live effect before this rule:
   /account/ showed the Six digit code box, Sign in and Start again before a
   code had been asked for, and the donate section showed Donate online even
   when Razorpay was switched off or the API was down. Every `hidden` toggle on
   this site depends on this one line. */
[hidden]{display:none!important}
.btn{display:inline-flex;align-items:center;gap:10px;padding:16px 28px;border-radius:999px;font:800 15.5px/1 var(--body);text-decoration:none;border:0;cursor:pointer;transition:transform .18s var(--ease),box-shadow .18s,background .18s}
.btn:hover{transform:translateY(-2px)}
.btn:active{transform:translateY(0)}
.btn-ink{background:var(--ink);color:#fff;box-shadow:var(--shadow)}
.btn-ink:hover{background:var(--lapis);box-shadow:var(--shadow-lift)}
.btn-line{background:var(--card);color:var(--ink);border:1px solid var(--hair-2)}
.btn-line:hover{border-color:var(--ink)}
.hero-stats{display:flex;gap:34px;flex-wrap:wrap}
.hero-stats b{display:block;font-family:var(--disp);font-weight:800;font-size:32px;letter-spacing:-.02em}
.hero-stats b em{font-style:normal;color:var(--copper-deep)}
.hero-stats span{font:600 14.5px/1.4 var(--body);color:var(--slate)}
.hero-art{position:relative;display:flex;justify-content:center}
.hero-art .halo{position:absolute;inset:8% 4%;border-radius:50%;background:radial-gradient(circle,rgba(185,124,52,.16),rgba(36,56,160,.08) 55%,transparent 72%);filter:blur(6px)}
.hero-art img,.hero-art video{position:relative;width:min(440px,88%);height:auto;filter:drop-shadow(0 24px 48px rgba(18,22,46,.22));opacity:0;transform:translateY(18px) scale(.97);transition:opacity 1.1s var(--ease),transform 1.1s var(--ease)}
.hero.lit .hero-art img,.hero.lit .hero-art video{opacity:1;transform:none}
/* Two things make the video's rectangle disappear.
   1. multiply: the clip's background was keyed to near-white, and multiplying
      near-white against the page leaves the page exactly as it was, while the
      bird and the gold keep their own colour. This is why no alpha channel is
      needed, which matters because Safari cannot play one.
   2. no drop-shadow: the file is opaque, so the shadow that flatters the
      cut-out still logo was drawing a shadow of the whole rectangle.
   The clip is also shown larger than the still was: the bird is a little over
   half its frame, so it has to be to read at the same size, and the gold ring
   is free to spread past the column now that there is no edge to give it away. */
.hero-art video{
  mix-blend-mode:multiply;filter:none;
  width:min(760px,164%);max-width:none}
/* The clip and the logo cross over each other in the same place, so the hero
   never jumps: the video sits on top and dissolves out as the still comes up. */
.hero-art video{position:absolute;top:50%;left:50%;translate:-50% -50%;z-index:1;
  transition:opacity .9s var(--ease)}
.hero.lit .hero-art video{opacity:1}
/* sound toggle */
.snd{position:absolute;right:6%;bottom:4%;z-index:2;display:inline-flex;align-items:center;gap:8px;
  min-height:40px;padding:9px 16px 9px 13px;border-radius:999px;cursor:pointer;
  background:rgba(255,255,255,.92);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  border:1px solid var(--hair-2);color:var(--ink);font:800 12.5px/1 var(--body);letter-spacing:.02em;
  box-shadow:var(--shadow);opacity:0;transition:opacity .5s var(--ease),background .2s,border-color .2s,transform .18s var(--ease)}
.hero.lit .snd{opacity:1}
.snd:hover{background:#fff;border-color:var(--lapis);transform:translateY(-2px)}
.snd svg{width:17px;height:17px;fill:currentColor;flex:none}
.snd .off{display:none}
.snd[aria-pressed="true"]{background:var(--lapis);border-color:var(--lapis);color:#fff}
.snd[aria-pressed="true"] .off{display:inline}
.snd[aria-pressed="true"] .on{display:none}

/* ---------- registry strip ---------- */
/* The trust's credentials — the reason a stranger believes this is real. They
   were plain label-and-value text; each is now a card carrying a verified tick. */
.registry{border-block:1px solid var(--hair);background:linear-gradient(180deg,var(--card),var(--paper))}
.registry ul{list-style:none;max-width:var(--maxw);margin:0 auto;padding:22px 24px;display:grid;grid-template-columns:repeat(5,1fr);gap:10px}
.registry li{position:relative;background:var(--card);border:1px solid var(--hair);border-radius:14px;
  padding:12px 15px;transition:border-color .25s var(--ease),box-shadow .25s var(--ease),transform .25s var(--ease)}
.registry li:hover{border-color:var(--hair-2);box-shadow:var(--shadow);transform:translateY(-2px)}
/* align-items:flex-start, not center: on a phone "Registered Trust" takes two
   lines and a centred tick floats between them, which is what the owner
   photographed on 2026-08-29. The tick belongs beside the FIRST line. */
.registry li b{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;font:800 11px/1.6 var(--body);letter-spacing:.12em;text-transform:uppercase;color:var(--slate)}
.registry li b::after{content:"✓";flex:none;width:16px;height:16px;border-radius:50%;
  background:#E5F4EC;color:var(--ok-on-soft);font:800 9px/16px var(--body);text-align:center;letter-spacing:0}
/* overflow-wrap, NOT word-break:break-all. break-all splits between any two
   characters the moment the line runs short, which is how "Reg No. 4/82/2026"
   came to read "4/82/202" over "6" on a phone: a registration number cut
   between its digits. This breaks only a token that cannot fit at all, and the
   phone sizes below are chosen so none of them has to. */
.registry li span{font:600 14px/1.5 var(--fig);font-variant-numeric:tabular-nums;color:var(--ink);overflow-wrap:anywhere}
.registry-note{max-width:var(--maxw);margin:0 auto;padding:0 24px 18px;font-size:14px;line-height:1.6;color:var(--slate);text-align:center}

/* ---------- sections ---------- */
section.block{padding:104px 0}
.sec-head{max-width:660px;margin-bottom:56px}
.sec-head h1,.sec-head h2{font-size:clamp(32px,4.2vw,52px);margin:16px 0 16px}
.sec-head p:not(.eyebrow){color:var(--slate);font-size:17.5px}
.tint{background:var(--mist)}

/* ---------- creed ---------- */
.creed-band{display:grid;grid-template-columns:1fr 1fr;gap:20px}
.creed-card{background:var(--card);border:1px solid var(--hair);border-radius:var(--r);padding:38px 40px;box-shadow:var(--shadow);position:relative;overflow:hidden}
.creed-card::after{content:"";position:absolute;inset:auto 0 0 0;height:3px;background:linear-gradient(90deg,var(--copper),var(--lapis))}
.creed-card .gl{font-family:var(--disp);font-weight:800;font-size:44px;letter-spacing:-.02em}
.creed-card:first-child .gl{color:var(--copper-deep)}
.creed-card:last-child .gl{color:var(--lapis)}
.creed-card h3{font-size:19px;font-weight:600;margin:6px 0 12px;color:var(--slate)}
.creed-card p{color:var(--slate);font-size:15.5px;max-width:44ch}
.creed-lede{font-family:var(--disp);font-weight:600;font-size:clamp(24px,3vw,34px);letter-spacing:-.01em;max-width:26ch;margin:14px 0 40px}
.creed-lede .glow{background:linear-gradient(92deg,var(--copper),var(--lapis));-webkit-background-clip:text;background-clip:text;color:transparent}

/* ---------- causes ---------- */
.cause-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
/* The trust's whole idea is carrying light, so each card lights up: a warm glow
   blooms from behind the number and a copper-to-lapis line draws itself across
   the top. Nine identical white boxes said nothing about Alorah. */
/* NOT SELECTABLE. Owner, 2026-08-30: "those 9 sections are text choosable.
   disable text selection and it should act as a button." The whole card has
   been one link since 2026-08-29, and a long press or a drag on a button that
   selects its own label is the card telling the reader it is a paragraph. The
   app has never had this: a React Native Text is not selectable unless it is
   asked to be. */
.cause{user-select:none;-webkit-user-select:none;
  position:relative;overflow:hidden;isolation:isolate;background:var(--card);
  border:1px solid var(--hair);border-radius:var(--r);padding:34px 30px 32px;
  transition:transform .3s var(--ease),box-shadow .3s var(--ease),border-color .3s}
.cause:hover{transform:translateY(-5px);box-shadow:var(--shadow-lift);border-color:var(--hair-2)}
/* Each cause card is now the door to its own page. The heading keeps the card's
   ink rather than turning link blue, and the ::after below stretches the hit
   area over the whole card so the tap target is the card, not nine words. */
.cause h3 a{color:inherit;text-decoration:none}
.cause h3 a::after{content:"";position:absolute;inset:0;z-index:1}
.cause:hover h3 a,.cause h3 a:focus-visible{color:var(--lapis)}
.cause h3 a:focus-visible{outline:2px solid var(--lapis);outline-offset:3px;border-radius:4px}
/* the lamp coming on */
.cause::after{content:"";position:absolute;z-index:-1;top:-55%;right:-35%;width:78%;height:130%;
  background:radial-gradient(circle at 50% 50%,rgba(185,124,52,.20),rgba(185,124,52,.05) 45%,transparent 70%);
  opacity:0;transform:scale(.7);transition:opacity .5s var(--ease),transform .6s var(--ease);pointer-events:none}
.cause:hover::after{opacity:1;transform:scale(1)}
/* the gradient hairline, drawn left to right */
.cause::before{content:"";position:absolute;inset:0 0 auto 0;height:3px;
  background:linear-gradient(90deg,var(--copper),var(--lapis));
  transform:scaleX(0);transform-origin:left;transition:transform .5s var(--ease)}
.cause:hover::before{transform:scaleX(1)}
/* the number becomes a ghosted display numeral instead of a small mono label */
.cause .n{position:absolute;top:16px;right:20px;font-family:var(--disp);font-weight:800;
  font-size:60px;line-height:1;letter-spacing:-.04em;color:var(--lapis);opacity:.07;
  transition:opacity .35s var(--ease),transform .35s var(--ease)}
.cause:hover .n{opacity:.14;transform:translateY(-3px)}
/* NO position:relative HERE. `.cause h3 a::after{inset:0}` is a stretched
   link, and a stretched link is anchored by the nearest POSITIONED ancestor.
   `position:relative` on this h3 made that ancestor the heading itself, so
   the overlay covered the two lines of the title and nothing else: the card
   looked like a button, and everywhere except the words was dead. It has been
   that way since the nine cause pages were built on 2026-08-23, because the
   `position:relative` predates them and nothing on this box has ever PRESSED
   anything. The card is the positioned ancestor now. */
.cause h3{font-family:var(--disp);font-weight:800;font-size:20px;margin:0 0 10px;letter-spacing:-.015em;
  max-width:15ch}
.cause h3::after{content:"";display:block;width:26px;height:2px;margin-top:12px;
  background:linear-gradient(90deg,var(--copper),var(--lapis));border-radius:2px;
  transition:width .4s var(--ease)}
.cause:hover h3::after{width:46px}
.cause p{font-size:14.5px;line-height:1.7;color:var(--slate);position:relative}
/* A column, so the cue can be pushed to the floor by margin-top:auto. */
.cause{display:flex;flex-direction:column}
/* "READ MORE" SITS ON THE FLOOR OF THE CARD, NOT AFTER THE COPY.
   It went in with the stretched-link fix, came out an hour later - owner:
   "when read more came there are many blank spces" - and went back in on his
   word: "Read more was good but it just needs to be aligned properly."
   Both readings were right about the same thing. The grid stretches every card
   in a row to the tallest, so a cue placed straight after the paragraph lands
   at a different height in every card, and the leftover space fell BELOW it as
   a ragged hole. Pinned to the bottom with margin-top:auto the slack moves
   ABOVE the cue instead, and the nine cues line up on one baseline across
   every row. That is what makes it read as aligned rather than as blank space.
   It is a span and not a second <a> on purpose: the card already is one link,
   and two links to one page is worse for a screen reader and for search. */
.cause .more{display:inline-flex;align-items:center;gap:6px;margin-top:auto;padding-top:14px;
  font:800 14px/1.4 var(--body);color:var(--lapis);position:relative}
.cause .more::after{content:"\2192";transition:transform .25s var(--ease)}
.cause:hover .more::after{transform:translateX(3px)}

/* ---------- project / live need ---------- */
.proj{background:var(--card);border:1px solid var(--hair);border-radius:calc(var(--r) + 6px);box-shadow:var(--shadow);overflow:hidden}
/* ---------- open needs: a slider ----------
   Stacking them vertically meant five open needs made the homepage enormous.
   One need per slide, swipeable on a phone (native scroll-snap — no library),
   with arrows and dots on wider screens. */
.needs{position:relative}
.needs-track{display:flex;gap:16px;overflow-x:auto;scroll-snap-type:x mandatory;
  scroll-behavior:smooth;-webkit-overflow-scrolling:touch;scrollbar-width:none;padding-bottom:4px}
.needs-track::-webkit-scrollbar{display:none}
.needs-track > .proj{flex:0 0 100%;scroll-snap-align:start;min-width:0}
.needs-nav{display:flex;align-items:center;gap:14px;margin-top:22px}
.needs-btn{width:44px;height:44px;flex:none;border-radius:50%;background:var(--card);
  border:1px solid var(--hair-2);color:var(--ink);font-size:17px;cursor:pointer;
  display:flex;align-items:center;justify-content:center;transition:border-color .2s,background .2s,opacity .2s}
.needs-btn:hover:not(:disabled){border-color:var(--lapis);color:var(--lapis);background:var(--lapis-soft)}
.needs-btn:disabled{opacity:.32;cursor:default}
.needs-dots{display:flex;gap:8px;margin-left:auto}
.needs-dot{width:9px;height:9px;border-radius:50%;border:0;padding:0;cursor:pointer;
  background:var(--hair-2);transition:background .25s var(--ease),width .25s var(--ease)}
.needs-dot.on{background:linear-gradient(90deg,var(--copper),var(--lapis));width:26px;border-radius:999px}
.needs-count{font:500 14px/1 var(--mono);color:var(--slate)}
.needs-nav.hide{display:none}
.needs-all{margin-top:18px}
.needs-all a{font:800 15px/1.6 var(--body);color:var(--lapis);text-decoration:none;
  border-bottom:2px solid var(--lapis-soft);padding-bottom:2px}
.needs-all a:hover{border-bottom-color:var(--lapis)}
@media (max-width:600px){
  .needs-track{gap:10px}
  .needs-nav{gap:10px}

}
.proj-top{display:grid;grid-template-columns:1.05fr .95fr;gap:0}
.proj-info{padding:44px 46px}
.chip{display:inline-flex;align-items:center;gap:7px;font:800 11px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;border-radius:999px;padding:8px 14px;margin-bottom:18px}
.chip-open{background:var(--copper-soft);color:var(--copper-on-soft)}
.chip-open::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--copper);
  animation:need-pulse 2.4s var(--ease) infinite}
/* A slow pulse, not a blink: it reads as "this need is still alive" without
   the harshness of flashing, which is distracting and an accessibility risk. */
@keyframes need-pulse{
  0%{box-shadow:0 0 0 0 rgba(185,124,52,.55);opacity:1}
  70%{box-shadow:0 0 0 8px rgba(185,124,52,0);opacity:.65}
  100%{box-shadow:0 0 0 0 rgba(185,124,52,0);opacity:1}
}
/* h1 as well as h3: the need's own page makes the title the page heading, and
   without this it fell back to the browser's default h1 size, which only
   happened to look right at desktop width. */
.proj-info h3,.proj-info h1{font-size:clamp(26px,2.8vw,34px);margin-bottom:6px}
/* A PLACE IS PROSE. "Coimbatore District" is not a code, a figure or a date,
   and the rule above has said so since 2026-08-29; this one was missed in that
   sweep because it is one line rather than a paragraph. */
.proj-info .loc{font:400 14px/1.6 var(--body);color:var(--slate);margin-bottom:18px;overflow-wrap:break-word}
.proj-info>p{color:var(--slate);font-size:15.5px;margin-bottom:28px;max-width:52ch}
.ledger{border:1px solid var(--hair);border-radius:var(--r-s);overflow:hidden;margin-bottom:14px}
.ledger-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}
/* THE FOURTH FIGURE. Owner, 2026-09-05: "why in the open needs this was not
   shown (not in raised but somewhere)", of ₹4,576 paid against a need that had
   raised ₹1,000. It is drawn only on the needs that have one, so a need nobody
   has been paid for keeps the three columns frozen on 2026-08-29 and this rule
   never reaches it. `Given so far` is copper like Still needed is: both are
   about what is happening beyond the donations, and two ink figures beside two
   coloured ones would read as two pairs. */
.ledger-row.four{grid-template-columns:repeat(4,minmax(0,1fr))}
.ledger-row .given b{color:var(--lapis)}
.ledger-row div{padding:16px 20px}
.ledger-row div+div{border-left:1px solid var(--hair)}
.ledger b{display:block;font:600 22px/1.3 var(--fig);font-variant-numeric:tabular-nums}
.ledger .short b{color:var(--copper-deep)}
.ledger span{font:800 10px/1.8 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--slate)}
.bar{height:8px;border-radius:999px;background:var(--mist);border:1px solid var(--hair);overflow:hidden;margin-bottom:10px}
.bar i{display:block;height:100%;width:0%;border-radius:999px;background:linear-gradient(90deg,var(--copper),var(--lapis));transition:width 1.2s var(--ease)}
.due{display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px;font:400 14px/1.7 var(--fig);font-variant-numeric:tabular-nums;color:var(--slate);margin-bottom:26px}
.due b{color:var(--ink);font-weight:500}
/* The panel starts at the top and ends on the 80G line, rather than floating in
   the middle of its own colour. Owner, 2026-08-28, circling the empty half:
   "why are we wasting this much space". */
/* space-between with margin-top:auto on the middle block: everything after the
   top block sits at the floor as one group. */
.proj-aside{background:linear-gradient(165deg,var(--lapis-deep),var(--lapis) 130%);color:#EDEFFA;padding:38px 42px;display:flex;flex-direction:column;justify-content:space-between;gap:22px}
.proj-aside h4{font-family:var(--disp);font-weight:600;font-size:21px;letter-spacing:-.01em}
.proj-aside p{font-size:14.5px;color:#C4CBEE;max-width:40ch;margin-top:8px}
.proj-aside .mono{font:500 13.5px/1.75 var(--body);color:#D8DDF5}
.pa-top{display:block}
/* What the whole thing costs, what we are raising, who covers the rest. */
.pa-split{margin-top:18px;display:flex;flex-direction:column;gap:12px;border-top:1px solid rgba(255,255,255,.16);padding-top:16px}
.pa-split div{display:flex;align-items:baseline;justify-content:space-between;gap:14px}
.pa-split b{font:600 17px/1.3 var(--fig);color:#fff;font-variant-numeric:tabular-nums;text-align:right;flex:none}
.pa-split span{font:800 10px/1.5 var(--body);letter-spacing:.13em;text-transform:uppercase;color:#B9C2EA;flex:1;min-width:0}
/* Between the figures and the 80G footer, which is where the space was. The
   label is small and the sentence is normal body copy: this is prose, so it
   never takes the mono face. */
/* margin-top:auto, so the free space collects ABOVE this block rather than
   being shared out between three of them. The panel then reads top, gap,
   bottom, instead of leaving two holes: the second hole is what the owner
   ringed in red. */
.pa-media{margin-top:auto;border-top:1px solid rgba(255,255,255,.16);padding-top:16px}
.pa-media b{display:block;font:800 12px/1.5 var(--body);letter-spacing:.13em;text-transform:uppercase;color:#fff}
.pa-media span{display:block;margin-top:6px;font:500 13.5px/1.7 var(--body);color:#C4CBEE}
.pa-foot{border-top:1px solid rgba(255,255,255,.16);padding-top:16px}
.pa-foot b{display:block;font:800 12px/1.5 var(--body);letter-spacing:.13em;text-transform:uppercase;color:#fff}
.pa-foot span{display:block;margin-top:5px;font:500 13px/1.6 var(--body);color:#C4CBEE}

/* ---------- photo timeline ---------- */
.ptl{border-top:1px solid var(--hair);padding:34px 46px 42px;background:var(--paper)}
/* Optional project video: click-to-play facade, iframe loads only on tap */
.ptl-video{margin:0 0 18px;border-radius:var(--r-s,14px);overflow:hidden;border:1px solid var(--hair);background:#000;max-width:720px}
.ptl-video .vwrap{position:relative;aspect-ratio:16/9}
.ptl-video .vfacade{position:absolute;inset:0;width:100%;height:100%;border:0;padding:0;cursor:pointer;background:#000;display:block}
.ptl-video .vfacade img{width:100%;height:100%;object-fit:cover;opacity:.85;display:block}
.ptl-video .vfacade:hover img{opacity:1}
.ptl-video .vplay{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:64px;height:64px;border-radius:50%;background:var(--lapis);color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 6px 24px rgba(18,22,46,.45)}
.ptl-video .vplay svg{width:24px;height:24px;margin-left:3px}
.ptl-video .vfacade:hover .vplay{background:var(--lapis-deep)}
.ptl-video iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
/* Privacy-sensitive needs: dignity note instead of the photo strip */
.ptl-note{border:1px dashed var(--hair-2);border-radius:var(--r-s,14px);background:var(--card);padding:22px 24px;max-width:720px;font:500 15px/1.7 var(--body);color:var(--slate)}
.ptl-note b{color:var(--ink)}
/* Delivered projects: same card, single info column, no funding UI */
/* HOW LITTLE TIME IS LEFT, and it carries NO dot of its own.
   Owner, 2026-08-29, on an earlier attempt at making a need feel live: "we
   don't need two dots for open need." The pulse belongs to `.chip-open` and
   nothing else on the row may grow a second one. */
.chip-urgent{background:#FBEAE7;color:#A32E22}
.chip-late{background:var(--mist);color:var(--slate)}
.chip-funded{background:var(--lapis-soft);color:var(--lapis)}
/* Verification. The waiting state is deliberately quiet and the verified state
   deliberately calm: a need that has not been checked yet must not look like a
   warning triangle, and one that has must not look like a sales badge. Both
   sit beside the funding chip, never instead of it. */
.chip-vwait{background:#F1EFE9;color:#5A5346;margin-left:8px}
.bar i{transition:width .8s cubic-bezier(.22,1,.36,1)}
@media (prefers-reduced-motion:reduce){
  .bar i{transition:none}
}
.chip-vok{background:#E9F6EE;color:var(--ok-on-soft);margin-left:8px}
.chip-vok::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--ok-on-soft)}

.chip-done{background:#E9F6EE;color:var(--ok-on-soft)}
#doneList .proj{flex:none}
#doneList .proj+.proj{margin-top:20px}
.proj.done .proj-top{grid-template-columns:1fr}

/* ---------- THE NEED'S OWN PAGE: the 2026-09-05 arrangement ----------

   Owner, 2026-09-05, on two screenshots of one need page: the photographs were
   below the fold ("many people did not even know a photo existed below") and
   the blue panel beside the story was half empty ("too much of blank space
   which is taking away the space hiding the content below"). Six layouts were
   rendered on the live page and photographed for him. He chose C with the
   phone stack lifted:

     Laptop  the lead photograph fills the top of the blue column. The story,
             the figures and Fund this need stay in the white column, where
             they already were.
     Phone   the photograph leads the card, above the chips and the title.

   THREE BLOCKS IN ONE GRID. The story, the money and the blue column are
   siblings of one grid rather than two nested columns, which is what lets the
   laptop keep the money on white while the phone lifts the photograph past it,
   from one markup and with no second copy of the figures.

   `.np` carries it, and only the need's own page has it: the homepage cards
   are `.proj` too and they keep `.proj-top`, because a card in a list is not
   this page. */
.proj.np{display:grid;grid-template-columns:1.05fr .95fr;grid-template-rows:auto 1fr auto}
.proj.np>.proj-info{grid-column:1;grid-row:1;padding-bottom:0}
.np-money{grid-column:1;grid-row:2;padding:0 46px 44px;align-self:start}
/* No background of its own: the photograph paints the flat deep lapis and the
   panel's own gradient starts at that same colour, so the two meet invisibly
   and a picture shown whole is letterboxed onto the panel rather than onto a
   colour that belongs to nothing. */
.np-right{grid-column:2;grid-row:1/3;display:flex;flex-direction:column}
.np-right>.proj-aside{flex:1}
/* THE SAME COLUMN ON THE HOMEPAGE CARD, which is a two column `.proj-top`
   rather than the need page's three row grid. Owner, 2026-09-05: "why is the
   homepage still like this", with the need page beside it: "this was approved".
   `grid-row:auto` because `.proj-top` has ONE row and the 1/3 above would open
   an implicit second one under the card. */
.proj-top>.np-right{grid-column:2;grid-row:auto}
.proj.np>.ptl{grid-column:1/-1;grid-row:3}
/* THE PHOTOGRAPH IS A CARD ON THE PANEL, NOT A PANE CUT INTO IT.
   Owner, 2026-09-05, an hour after this went live, circling the picture:
   *"can we neatly align the photo with curved edges, transparent, faded or
   some other best border."* It ran edge to edge, so a picture the trustee
   chose to show WHOLE was letterboxed against three hard corners and the
   navy showed as two bars that read like a mistake. Inset by the same
   amount on every side, rounded, with a hairline and a soft shadow, the
   letterboxing reads as a mount instead. */
.np-lead{background:var(--lapis-deep);overflow:hidden;padding:22px}
.np-lead figure{margin:0;position:relative;cursor:zoom-in;border-radius:16px;overflow:hidden;
  background:var(--lapis-deep);box-shadow:0 0 0 1px rgba(255,255,255,.16),0 18px 40px rgba(0,0,0,.30)}
/* 4:3, and the picture is drawn with the fit, the zoom and the point the
   trustee chose in the console: the lead and its tile in the strip are one
   record, so they cannot frame the same photograph differently. */
.np-lead img{display:block;width:100%;aspect-ratio:4/3}
.np-lead figure:focus-visible{outline:3px solid #fff;outline-offset:-4px}
.np-lead .vplay{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:64px;height:64px;border-radius:50%;
  background:var(--lapis);color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 6px 24px rgba(18,22,46,.45)}
.np-lead .vplay svg{width:24px;height:24px;margin-left:3px}
/* ONE COLUMN, AND THE PHOTOGRAPH LEADS. A delivered need has little to put in
   two columns, so it stacks on any screen exactly as a phone does. These five
   lines and the ones in the 920px block below are the same decision written
   twice: change one and change the other. */
.proj.np.done,.proj.np.done>*{grid-column:1;grid-row:auto}
.proj.np.done{grid-template-columns:minmax(0,1fr);grid-template-rows:none}
.proj.np.done .np-right{display:contents}
.proj.np.done .np-lead{order:0}
.proj.np.done>.proj-info{order:1}
.proj.np.done .np-money{order:2}
.proj.np.done .proj-aside{order:3}
.proj.np.done>.ptl{order:4}
.ptl-head{display:flex;justify-content:space-between;align-items:baseline;gap:16px;flex-wrap:wrap;margin-bottom:22px}
.ptl-head h4{font-family:var(--disp);font-weight:600;font-size:19px}
.ptl-head span{font:500 14px/1.6 var(--body);color:var(--slate)}
.ptl-track{display:grid;grid-auto-flow:column;grid-auto-columns:min(240px,68vw);gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;padding-bottom:8px}
.ptl-track::-webkit-scrollbar{height:8px}
.ptl-track::-webkit-scrollbar-thumb{background:var(--hair-2);border-radius:99px}
.stage{scroll-snap-align:start;border:1px solid var(--hair);border-radius:var(--r-s);overflow:hidden;background:var(--card)}
/* THE FRAME CLIPS WHAT IS IN IT. Owner, 2026-09-05, of the fourth tile on a
   need whose photograph he had zoomed to 120%: *"what happened here to the
   title and image."* The picture was drawn at 1.2x and ran out of its own
   frame, down over its caption. `.stage` clips at the card edge, so the
   overhang stopped at the card and covered the title on the way.
   Every other framed picture on this site already clips: the lead photograph,
   the /needs/ card and the update photograph. This one was the tile the zoom
   was invented for and it was the one place the rule was missing. */
.stage figure{aspect-ratio:4/3;overflow:hidden;background:
  linear-gradient(150deg,var(--mist),#EDEDF4 60%,var(--lapis-soft));display:flex;align-items:center;justify-content:center;position:relative}
.stage figure.filled{background:none}
.stage figure .ph{font:600 12px/1.5 var(--body);color:var(--slate);text-align:center;padding:0 18px}
.stage figcaption{padding:12px 16px 14px;border-top:1px solid var(--hair)}
.stage figcaption b{display:block;font:800 11px/1.8 var(--body);letter-spacing:.12em;text-transform:uppercase;color:var(--lapis)}
.stage figcaption span{font:500 13.5px/1.6 var(--body);color:var(--slate)}

/* ---------- transparency ---------- */
.vault{display:flex;flex-direction:column;gap:14px}
.fy{background:var(--card);border:1px solid var(--hair);border-radius:var(--r);padding:26px 30px;display:grid;grid-template-columns:200px 1fr;gap:22px;align-items:start}
.fy .yr{font-family:var(--disp);font-weight:800;font-size:23px;letter-spacing:-.01em}
.fy .yr small{display:block;font:600 13.5px/1.8 var(--body);color:var(--slate)}
.docs{display:flex;flex-wrap:wrap;gap:10px}
.doc{display:inline-flex;align-items:center;gap:10px;border:1px solid var(--hair);border-radius:999px;padding:10px 18px;font:600 14px/1 var(--body);color:var(--ink);text-decoration:none;background:var(--paper)}
.doc .st{font:800 11px/1 var(--body);letter-spacing:.1em;text-transform:uppercase;padding:5px 10px;border-radius:999px}
.st-soon{background:var(--mist);color:var(--slate)}
.st-live{background:#E5F4EC;color:var(--ok-on-soft)}
/* registrations row: three fixed cards on one line */
.docs-reg{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;width:100%}
.docs-reg .doc{display:grid;grid-template-columns:1fr auto;align-items:center;gap:3px 10px;border-radius:14px;padding:13px 16px}
.docs-reg .doc>b{font:800 13.5px/1.3 var(--body)}
.docs-reg .doc .code{grid-column:1/-1;font:600 13.5px/1.4 var(--fig);font-variant-numeric:tabular-nums;color:var(--slate);letter-spacing:.02em}
.docs-reg .doc .st{flex:none;justify-self:end}
/* masked donor wall + beneficiaries */
.people{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:14px}
.people-card{background:var(--card);border:1px solid var(--hair);border-radius:var(--r);padding:24px 26px}
.people-card h3{font-size:18px;margin-bottom:2px}
.people-card .sub{font:600 14px/1.6 var(--body);color:var(--slate);margin-bottom:10px}
.people-card ul{list-style:none}
.people-card li{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:11px 0;border-top:1px solid var(--hair)}
.people-card li:first-child{border-top:0}
.people-card li b{font-weight:800;font-size:14.5px}
/* A city, a date and a benefit, joined by a middot: "Coimbatore \u00b7 17 Aug
   2026". Mostly prose, so the body face, for the same reason as .proj-info
   .loc. The date inside it does not make the line data. */
.people-card li small{display:block;font:400 13px/1.6 var(--body);color:var(--slate)}
.people-card li .amt{font:600 14px/1.4 var(--fig);font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--ink)}
.people-card li .pc{font:700 11px/1.5 var(--body);color:var(--lapis);background:var(--lapis-soft);border-radius:999px;padding:3px 10px;text-align:right}
.people-card .empty{color:var(--slate);font-size:14px;border-top:0;display:block}
/* SHOW MORE, NOT A SCROLLBAR. Owner asked whether the wall needs one. An inner
   scroll area on a page section traps a thumb on a phone (the outer page and
   the inner list fight over the same gesture) and it hides the one number the
   wall exists to publish. Ten rows, the real total beside the heading, and a
   button that expands in place. */
.people-card .sub span{color:var(--copper-deep);font-weight:800}
.people-card .sub .nb{white-space:nowrap}
.people-card .more{margin-top:12px;width:100%;min-height:44px;background:var(--paper);
  border:1px solid var(--hair-2);border-radius:999px;cursor:pointer;
  font:800 14px/1.5 var(--body);color:var(--lapis);transition:border-color .2s var(--ease),background .2s var(--ease)}
.people-card .more:hover{border-color:var(--lapis);background:var(--lapis-soft)}
.people-card .more:focus-visible{outline:2px solid var(--lapis);outline-offset:2px}
.vault-note{margin-top:18px;background:var(--card);border:1px solid var(--hair);border-left:4px solid var(--copper);border-radius:var(--r-s);padding:18px 22px;font-size:14.5px;line-height:1.75;color:var(--slate);max-width:none}
.vault-note b{color:var(--ink)}
.vault-note a{color:var(--lapis);font-weight:600}

/* ---------- donate ---------- */
.donate-grid{display:grid;grid-template-columns:1fr 1fr;gap:20px;align-items:start}
.pay-card{background:var(--card);border:1px solid var(--hair);border-radius:var(--r);box-shadow:var(--shadow);padding:36px 38px}
.pay-card h3{font-size:22px;margin-bottom:8px}
.pay-card>p{font-size:14.5px;color:var(--slate);margin-bottom:24px}
.field-row{display:flex;justify-content:space-between;align-items:center;gap:14px;border:1px solid var(--hair);border-radius:var(--r-s);padding:7px 12px;margin-bottom:8px;background:var(--paper)}
/* Height comes from two stacked lines, not padding, so the line-heights are what
   bring these down to 56px. Both font sizes are deliberately left alone. */
.field-row div b{display:block;font:800 10px/1.3 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--slate)}
/* break-word, not anywhere: `anywhere` also shrinks the box's min-content size,
   which lets this value shrink to nothing inside a flex row instead of pushing
   the Copy button onto its own line where there is no room for both. */
.field-row div span{font:600 15.5px/1.25 var(--fig);font-variant-numeric:tabular-nums;color:var(--ink);overflow-wrap:break-word}
.copy{flex:none;background:var(--mist);border:1px solid var(--hair);border-radius:8px;padding:8px 14px;font:800 12px/1 var(--body);color:var(--ink);cursor:pointer;transition:background .2s}
.copy:hover{background:var(--lapis-soft)}
.copy.done{background:#E5F4EC;color:var(--ok-on-soft);border-color:#BFE3CE}
.upi-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:18px}
.pay-note{font:500 13.5px/1.75 var(--body);color:var(--slate);margin-top:16px}

/* donor form */
.dform{background:var(--card);border:1px solid var(--hair);border-radius:var(--r);box-shadow:var(--shadow);padding:36px 38px;margin-top:20px}
.dform h3{font-size:22px;margin-bottom:8px}
.dform>p{font-size:14.5px;color:var(--slate);margin-bottom:26px;max-width:64ch}
.steps{list-style:none;counter-reset:step;display:flex;flex-direction:column;gap:12px;margin:18px 0 10px}
.steps li{counter-increment:step;position:relative;padding-left:46px;font-size:14.5px;line-height:1.6;color:var(--slate);max-width:70ch}
.steps li b{color:var(--ink)}
.steps li::before{content:counter(step);position:absolute;left:0;top:0;width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,var(--lapis),var(--lapis-deep));color:#fff;font:800 15px/32px var(--body);text-align:center;box-shadow:0 2px 8px rgba(36,56,160,.28)}
.steps li+li::after{content:"";position:absolute;left:15.5px;top:-14px;height:14px;width:2px;background:var(--lapis-soft)}
.dform>p.steps-note{font-size:13px;color:var(--slate);margin-bottom:24px;max-width:70ch}
.fgrid{display:grid;grid-template-columns:1fr 1fr;gap:16px 18px}
.f{display:flex;flex-direction:column;gap:6px}
.f.full{grid-column:1/-1}
.f label{font:800 14px/1.4 var(--body);letter-spacing:.06em;color:var(--ink)}
.f label small{font-weight:600;color:var(--slate);letter-spacing:0}
/* 16px is deliberate: below it, iOS Safari zooms the page in on every tap.
   Tighter padding keeps the box compact despite the slightly larger text
   (was 13px/15.5px = ~51px tall; now ~42px). */
.f input,.f select,.f textarea{font:500 15.5px/1.5 var(--body);color:var(--ink);background:var(--paper);border:1px solid var(--hair-2);border-radius:var(--r-s);padding:9px 12px;transition:border-color .2s,box-shadow .2s;width:100%}
.f input:focus,.f select:focus,.f textarea:focus{outline:none;border-color:var(--lapis);box-shadow:0 0 0 3px var(--lapis-soft)}
.f input.bad,.f textarea.bad{border-color:#C0392B;box-shadow:0 0 0 3px #F9E4E1}
.f .err{font:600 13.5px/1.5 var(--body);color:#C0392B;min-height:0;display:none}
.f .err.show{display:block}
/* PAN, IFSC, an account number, an amount: the donor checks these back by
   eye before pressing send, so they are the figure face, not the mono one. */
.f input[data-mono],.f textarea[data-mono]{font-family:var(--fig);font-variant-numeric:tabular-nums}
/* The summary that names what is still wrong, sitting directly above the
   buttons. #8E2A1E on #FBEDEA measures 7.4:1, so it clears AA at this size and
   stays readable to anyone who cannot pick the red field marks out by colour. */
.form-missing{font:600 14px/1.5 var(--body);color:#8E2A1E;background:#FBEDEA;border:1px solid #EFC9C3;border-radius:10px;padding:12px 14px;margin:22px 0 0}
.form-missing[hidden]{display:none}
.dform-actions{display:flex;gap:12px;flex-wrap:wrap;margin-top:26px;align-items:center}
.dform>p.dform-note{max-width:none;font:500 14px/1.75 var(--body);color:var(--slate);margin-top:16px;text-align:left}
.form-ok{display:none;margin-top:18px;background:#E5F4EC;border:1px solid #BFE3CE;color:var(--ok-on-soft);border-radius:var(--r-s);padding:14px 18px;font:600 14px/1.6 var(--body)}
.form-ok.show{display:block}
/* The double-payment warning cannot wear the green of a success message, and it
   cannot be a confirm() either: Chrome lets a visitor permanently suppress that
   dialog, and a suppressed warning here means somebody pays twice. */
.form-ok.warn{background:var(--copper-soft);border-color:#E8D3AE;color:var(--copper-on-soft)}

/* ---------- csr ---------- */
.csr-band{display:grid;grid-template-columns:1.25fr .75fr;gap:20px;background:linear-gradient(165deg,var(--lapis-deep),var(--lapis) 140%);border-radius:calc(var(--r) + 6px);padding:52px 54px;color:#EDEFFA;box-shadow:var(--shadow-lift)}
.csr-band .eyebrow{color:#C9A265}
.csr-band .eyebrow::before{background:linear-gradient(90deg,#C9A265,#8E99D8)}
.csr-band h2{font-size:clamp(28px,3.6vw,44px);margin:16px 0 16px;color:#fff}
.csr-band>div>p:not(.eyebrow){color:#C4CBEE;font-size:16px;max-width:60ch;margin-bottom:26px}
.csr-points{list-style:none;display:flex;flex-direction:column;gap:14px;margin-bottom:32px}
.csr-points li{font-size:14.5px;color:#C4CBEE;max-width:60ch}
.csr-points b{display:block;font:800 14.5px/1.7 var(--body);color:#fff}
.csr-band .btn-ink{background:#fff;color:var(--lapis-deep)}
.csr-band .btn-ink:hover{background:var(--copper-soft)}
.csr-side{background:rgba(255,255,255,.06);border:1px solid rgba(216,221,245,.18);border-radius:var(--r);padding:30px 32px;align-self:center}
.csr-side h4{font:800 11px/1 var(--body);letter-spacing:.2em;text-transform:uppercase;color:#C9A265;margin-bottom:18px}
.csr-side ul{list-style:none;display:flex;flex-direction:column;gap:12px}
.csr-side li{font-size:14.5px;color:#EDEFFA;padding-left:18px;position:relative}
.csr-side li::before{content:"";position:absolute;left:0;top:.55em;width:8px;height:2px;background:#C9A265}

/* ---------- whatsapp fab ---------- */
.wa-fab{position:fixed;right:22px;bottom:22px;z-index:48;width:56px;height:56px;border-radius:50%;background:#25D366;color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 6px 24px rgba(18,22,46,.28);transition:transform .2s var(--ease)}
.wa-fab:hover{transform:scale(1.08)}
@media print{.wa-fab{display:none}}

/* ---------- photo lightbox ---------- */
/* Owner, 2026-08-28, asking about video on open needs: "so that anyone can
   expand and see". The video already expanded, by playing. A photograph in the
   timeline did not: it was cropped into a small tile and that was as close as
   anybody could get to it. These are the only pictures the trust publishes of
   the work it has done, so they are worth looking at properly. */
.lbx{position:fixed;inset:0;z-index:120;display:none;align-items:center;justify-content:center;
  background:rgba(12,14,28,.93);padding:20px}
.lbx.on{display:flex}
.lbx-fig{max-width:min(1100px,100%);max-height:100%;display:flex;flex-direction:column;gap:12px;margin:0}
.lbx-fig img{max-width:100%;max-height:calc(100vh - 150px);object-fit:contain;border-radius:10px;background:#000;display:block;margin:0 auto}
.lbx-cap{color:#F3F1EC;font:500 14px/1.6 var(--body);text-align:center;max-width:70ch;margin:0 auto}
.lbx-cap b{display:block;font:800 13px/1.6 var(--body);letter-spacing:.1em;text-transform:uppercase;color:#CFCCC3;margin-bottom:4px}
/* Opaque, so the contrast of the cross can be MEASURED rather than assumed:
   white on #2B2F49 is about 11:1 wherever the photograph behind it happens to
   be light. */
.lbx-close{position:absolute;top:14px;right:14px;width:48px;height:48px;border-radius:50%;border:0;cursor:pointer;
  background:#2B2F49;color:#fff;font:700 24px/1 var(--body);display:flex;align-items:center;justify-content:center}
.lbx-close:hover,.lbx-close:focus-visible{background:#3D4266}
.lbx-video{width:min(1100px,92vw);aspect-ratio:16/9;background:#000;border-radius:10px;overflow:hidden;display:none}
.lbx-video iframe{width:100%;height:100%;border:0;display:block}
/* The play badge on a stage that is a film rather than a picture. */
.ptl-track figure.has-video{position:relative}
.vplay-sm{width:44px;height:44px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  border-radius:50%;background:var(--lapis);color:#fff;display:flex;align-items:center;justify-content:center;
  box-shadow:0 4px 16px rgba(18,22,46,.45);pointer-events:none}
.vplay-sm svg{width:18px;height:18px;margin-left:2px}
/* The tile has to say it can be opened. */
.ptl-track figure.filled{cursor:zoom-in}
.ptl-track figure.filled:focus-visible{outline:3px solid var(--lapis);outline-offset:2px}
@media (max-width:600px){
  .lbx{padding:12px}
  .lbx-fig img{max-height:calc(100vh - 190px)}
}

/* ---------- fcra ---------- */
.fcra-note{margin-top:20px;background:var(--copper-soft);border:1px solid #EBD9B8;border-radius:var(--r-s);padding:16px 20px;font-size:14px;color:var(--copper-on-soft);max-width:100%}

/* ---------- share a need ---------- */
/* Resting state is on-theme (paper, hairline, slate). The platform colour only
   appears on hover/focus, so a row of four buttons does not turn a need card
   into a strip of logos. */
.proj-cta{display:flex;align-items:center;gap:16px 20px;flex-wrap:wrap;margin-top:4px}
.share{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.share-lbl{font:800 10.5px/1 var(--body);letter-spacing:.16em;text-transform:uppercase;color:var(--slate)}
.sh{width:40px;height:40px;flex:none;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;
  background:var(--card);border:1px solid var(--hair-2);color:var(--slate);cursor:pointer;text-decoration:none;
  transition:background .2s var(--ease),border-color .2s var(--ease),color .2s var(--ease),transform .18s var(--ease)}
.sh svg{width:17px;height:17px;fill:currentColor;pointer-events:none}
.sh:hover{transform:translateY(-2px)}
.sh-wa:hover,.sh-wa:focus-visible{background:#1D9E4B;border-color:#1D9E4B;color:#fff}
.sh-fb:hover,.sh-fb:focus-visible{background:#1877F2;border-color:#1877F2;color:#fff}
.sh-x:hover,.sh-x:focus-visible{background:#12162E;border-color:#12162E;color:#fff}
.sh-link:hover,.sh-link:focus-visible{background:var(--lapis);border-color:var(--lapis);color:#fff}
.sh-link.done{background:#E5F4EC;border-color:#BFE3CE;color:var(--ok-on-soft);transform:none}

/* ---------- upi qr ---------- */
.upi-qr{margin-top:20px;display:flex;align-items:center;gap:18px;background:var(--paper);border:1px solid var(--hair);border-radius:var(--r-s);padding:16px 18px}
.upi-qr img{width:132px;height:132px;flex:none;border-radius:8px;background:#fff}
.upi-qr p{font:500 13.5px/1.7 var(--body);color:var(--slate)}
.upi-qr p b{display:block;font:800 13.5px/1.5 var(--body);color:var(--ink);letter-spacing:0;margin-bottom:3px}

/* ---------- the two online paths: gateway and UPI QR ---------- */
/* Owner, 2026-08-13: show both, and say plainly what separates them. The notes
   never mention a charge to the DONOR: the gateway fee is the trust's expense
   and the donor is charged exactly what they typed (settled 2026-07-17). What
   differs for the donor is how fast the receipt can follow. */
.pay-choice{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:18px}
.pay-choice p{background:var(--paper);border:1px solid var(--hair);border-radius:var(--r-s);
  padding:14px 17px;font-size:13.5px;line-height:1.7;color:var(--slate);margin:0}
.pay-choice p b{display:block;color:var(--ink);font:800 14px/1.5 var(--body);margin-bottom:3px}
/* THE BENEFICIARY REFERENCE. A code, so the mono face, and the sentence under
   it is body copy, so it is not. Label, code, then the promise, each on its own
   line at every width: three things on one line is what put "Reg No. 4/82/202"
   over "6" on a phone in August. */
.ben-ref{margin:14px 0 0;display:flex;flex-direction:column;gap:3px}
.ben-ref span{font:800 10px/1.5 var(--body);letter-spacing:.13em;text-transform:uppercase;color:var(--slate)}
.ben-ref b{font:600 15px/1.4 var(--fig);font-variant-numeric:tabular-nums;color:var(--ink);letter-spacing:.02em}
.ben-ref em{font:500 13px/1.6 var(--body);font-style:normal;color:var(--slate)}

/* THE FUND'S OWN NEEDS, in the aside. Each row is one tap target of its own,
   44px tall, because on a phone this list IS the navigation to those needs. */
.fund-list{list-style:none;margin:16px 0 0;padding:0;display:flex;flex-direction:column;gap:2px}
.fund-list a{display:flex;flex-direction:column;gap:2px;padding:11px 0;min-height:44px;
  justify-content:center;text-decoration:none;border-top:1px solid rgba(255,255,255,.16)}
.fund-list li:first-child a{border-top:0}
.fund-list b{font:800 14.5px/1.45 var(--body);color:#fff}
.fund-list span{font:600 13px/1.6 var(--fig);color:#C4CBEE;font-variant-numeric:tabular-nums}
.fund-list a:hover b{text-decoration:underline}

/* THE AMOUNT CHIPS.

   A GRID, NOT A WRAPPED ROW. Owner, 2026-08-30: "Align these neatly." Six pills
   of six different widths wrapped into two ragged lines that shared no edge
   with each other or with the box below them. Equal columns give one grid, and
   `auto-fit` keeps it three up on a phone and four or more where there is room.

   WEIGHT 500, NOT 800. Same owner, same message: "should we remove the bold
   because the dot inside 0 is causing confusion". Spline Sans Mono draws a
   dotted zero, and at 800 on a small pill the dot reads as a decimal point in
   the middle of ₹200. Every other money figure on this site is mono 500 for
   the same reason, so this now matches the ledger rather than shouting over it.

   The box below is still where any other figure is typed: a chip is a shortcut,
   never a menu of what the trust will accept. 44px tall, because they are the
   first thing a thumb meets on this form, and the chosen one carries
   aria-pressed as well as colour. */
/* THREE COLUMNS, at every width. auto-fit fitted five across the desktop
   column and left the sixth alone on a line of its own, which is the ragged
   shape this was fixing. Three is a whole number of the six rungs the trust
   ships with, so the grid is two full rows on a phone and two full rows beside
   the PIN code. */
#fAmt{grid-column-start:1}
.amt-chips{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:8px;margin-top:10px}
.amt-chip{min-height:44px;padding:11px 10px;border-radius:999px;cursor:pointer;
  background:var(--card);border:1.5px solid var(--hair-2);color:var(--ink);
  font:600 15px/1 var(--fig);font-variant-numeric:tabular-nums;
  white-space:nowrap;text-align:center;
  transition:border-color .18s,background .18s,color .18s}
.amt-chip:hover{border-color:var(--ink)}
.amt-chip[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff}
.amt-chip:focus-visible{outline:2px solid var(--lapis);outline-offset:2px}

/* THE WORKED EXAMPLE. Owner, 2026-08-30: "can we show a short example with 100
   rupees so donor understands because some thing 18 percent is on the overall
   donation instead of the 2 percent." Two percentages in one sentence read as
   20% of the gift to anyone who does not stop to parse them, so the rupees are
   printed. Set apart from the paragraph above it, and never in the mono face:
   this is a sentence, not a figure. */
.pay-choice .fee-eg{display:block;margin-top:9px;padding-top:9px;
  border-top:1px solid var(--hair);color:var(--ink)}

.qr-panel{margin-top:20px;background:var(--card);border:1px solid var(--hair-2);
  border-radius:var(--r-s);padding:22px;box-shadow:var(--shadow)}
.qr-panel .qr-in{display:flex;gap:24px;align-items:flex-start}
.qr-panel img{width:220px;height:220px;flex:none;background:#fff;border:1px solid var(--hair);
  border-radius:12px;padding:8px}
.qr-side{min-width:0;flex:1}
.qr-side h4{font:800 17.5px/1.4 var(--body);color:var(--ink);margin-bottom:8px}
.qr-side p{font-size:14px;line-height:1.72;color:var(--slate);margin-bottom:12px;max-width:52ch}
/* .qr-side p is (0,1,1) and would otherwise beat a bare .qr-ref on font and
   colour, so the reference is matched with both. */
.qr-side p.qr-ref{display:inline-block;font:700 13.5px/1.5 var(--fig);font-variant-numeric:tabular-nums;color:var(--lapis-deep);
  background:var(--lapis-soft);border-radius:8px;padding:9px 13px;overflow-wrap:anywhere;max-width:100%}
.qr-side p.qr-ref span{display:block;font:600 10.5px/1.6 var(--body);letter-spacing:.1em;
  text-transform:uppercase;color:var(--slate)}
/* A upi:// link has nothing to open on a desktop, so a button that does
   nothing must not be drawn there. It appears only where a finger is the
   pointer, and on that screen it comes FIRST, because nobody can scan a code
   on the very phone they are holding. */
.qr-open{display:none;margin-bottom:14px}
@media (pointer:coarse){.qr-open{display:inline-flex}}

/* THE "NOTHING IS DEDUCTED" NOTE, owner 2026-08-17. It is the reason a donor
   would choose this path over the gateway, so it is the first thing in the
   panel rather than a line of small print under the code.
   Green on green: --ok-on-soft (#187245) on #E5F4EC measures 5.23:1, where the
   brand --ok would read 4.41. #E5F4EC is the
   soft green every other panel on this site uses; this block briefly carried a
   one-off #E7F5EC, which is the shape that lets a palette drift apart. */
.qr-free{display:block;background:#E5F4EC;border:1px solid #BFE3CE;border-radius:10px;
  padding:12px 15px;margin:0 0 18px;font:800 14px/1.6 var(--body);color:var(--ok-on-soft)}
.qr-free-inline{color:var(--ok)}
/* The glow the owner asked for, on the note and not on the whole panel: a
   pulsing card is hard to read, and this is the sentence that has to land.
   Reduced motion switches it for a plain steady ring, never nothing: the
   emphasis is information, not decoration. */
@media (prefers-reduced-motion:no-preference){
  .qr-free{animation:qrGlow 2.4s ease-in-out 3}
}
@media (prefers-reduced-motion:reduce){
  .qr-free{box-shadow:0 0 0 3px rgba(27,127,77,.16)}
}
@keyframes qrGlow{
  0%,100%{box-shadow:0 0 0 0 rgba(27,127,77,0)}
  50%{box-shadow:0 0 0 5px rgba(27,127,77,.20)}
}

.qr-done-ask{margin-top:20px;padding-top:18px;border-top:1px solid var(--hair)}
.qr-nudge{margin-top:12px;font-size:13.5px;line-height:1.7;color:var(--copper-on-soft);
  background:var(--copper-soft);border-radius:8px;padding:11px 14px;max-width:60ch}
.qr-nudge b{color:var(--copper-on-soft)}

.qr-paid-head{font:800 17.5px/1.45 var(--body);color:var(--ok);margin-bottom:14px}
#qrPaidPanel .qr-ref{display:inline-block;font:700 13.5px/1.5 var(--fig);font-variant-numeric:tabular-nums;color:var(--lapis-deep);
  background:var(--lapis-soft);border-radius:8px;padding:9px 13px;overflow-wrap:anywhere;max-width:100%}
#qrPaidPanel .qr-ref span{display:block;font:600 10.5px/1.6 var(--body);letter-spacing:.1em;
  text-transform:uppercase;color:var(--slate)}
.qr-paid-step{font-size:14px;line-height:1.72;color:var(--slate);margin:16px 0 16px;max-width:56ch}
.qr-paid-step b{color:var(--ink)}
/* Never edge to edge with the reference chip above it: React Native does not
   collapse margins and neither does this, so the gap is declared. */
.qr-wa{margin-bottom:14px}
.qr-paid-note{font-size:13px;line-height:1.7;color:var(--slate);max-width:56ch}

/* The tick box that lets a donor cover the gateway charge.

   LIGHT AND NEAT, owner 2026-08-17, and the same instruction as "do not
   frighten the customer": no filled panel, no heavy border, nothing that reads
   as a warning box. A hairline, a real 20px control and two short lines. The
   whole row is the target, because a 20px square is not one. */
.fee-opt{display:flex;gap:11px;align-items:flex-start;margin:16px 0 18px;padding:11px 13px;
  border:1px solid var(--hair);border-radius:10px;cursor:pointer;
  transition:border-color .15s var(--ease),background .15s var(--ease)}
.fee-opt:hover{border-color:var(--lapis)}
.fee-opt:focus-within{outline:2px solid var(--lapis);outline-offset:2px}
.fee-opt input{width:20px;height:20px;flex:none;margin-top:1px;accent-color:var(--lapis);cursor:pointer}
.fee-copy{min-width:0}
.fee-opt b{display:block;font:700 13.5px/1.55 var(--body);color:var(--ink)}
.fee-sub{display:block;margin-top:2px;font-size:13.5px;line-height:1.6;color:var(--slate)}

/* ---------- faqs ---------- */
.faqs{display:grid;gap:10px;max-width:900px}
.faq{background:var(--card);border:1px solid var(--hair);border-radius:var(--r-s);
  transition:border-color .22s var(--ease),box-shadow .22s var(--ease)}
.faq[open]{border-color:var(--hair-2);box-shadow:var(--shadow)}
.faq summary{list-style:none;cursor:pointer;display:flex;align-items:flex-start;gap:16px;
  padding:17px 22px;font:800 16px/1.55 var(--body);color:var(--ink);border-radius:var(--r-s)}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{background:var(--mist)}
.faq[open] summary{background:transparent}
/* chevron: two borders rotated, so it inherits colour and needs no image */
.faq summary::after{content:"";flex:none;margin-left:auto;margin-top:6px;width:10px;height:10px;
  border-right:2px solid var(--lapis);border-bottom:2px solid var(--lapis);
  transform:rotate(45deg);transition:transform .25s var(--ease)}
.faq[open] summary::after{transform:rotate(-135deg);margin-top:10px}
.faq .a{padding:0 22px 20px;color:var(--slate);font-size:15px;line-height:1.78;max-width:74ch}

/* ---------- need page (/need/<slug>/) ---------- */
/* Server-rendered from the database, reusing the card classes above so a need
   reads the same whether it is on the homepage or on its own page. */
.crumbs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font:600 14px/1.6 var(--body);color:var(--slate);margin-bottom:22px}
.crumbs a{color:var(--lapis);text-decoration:none}
.crumbs a:hover{text-decoration:underline}
.crumbs span[aria-current]{color:var(--slate)}
.need-page{padding:132px 0 0}
.need-page .proj{margin-bottom:26px}
/* CONTENT PAGES: /about/, /causes/..., /80g-tax-benefit/ and the rest.
   They carry the site's fixed nav, so they clear it exactly as a need page
   does. Deliberately no .rv on any of them: .rv sits at opacity 0 until an
   IntersectionObserver fires, and a page whose entire purpose is to be read
   by a crawler and by a stranger must not depend on script to become visible. */
.doc-page{padding:132px 0 0}
.doc-col{max-width:72ch;margin:0 auto}
.doc-col>*{max-width:100%}
/* A WIDE CONTENT PAGE: the prose keeps its reading width, everything else gets
   the wrap. Used by /needs/, where three cards inside a 72ch column came out
   200px wide each. */
.doc-col-wide{max-width:none}
.doc-col-wide>h1,.doc-col-wide>.lede,.doc-col-wide>p{max-width:72ch}
.doc-page h1{font-size:clamp(30px,5vw,46px);line-height:1.14;letter-spacing:-.02em;margin-bottom:14px}
.doc-page .lede{margin-bottom:24px}
.doc-page h2{font-size:clamp(21px,2.6vw,27px);letter-spacing:-.01em;margin:40px 0 12px}
.doc-page h3{font-size:17.5px;margin:26px 0 6px}
.doc-page p,.doc-page li{color:var(--slate)}
.doc-page p{margin-bottom:14px}
.doc-page ul,.doc-page ol{margin:0 0 16px;padding-left:22px}
.doc-page li{margin-bottom:7px}
.doc-page a:not(.btn){color:var(--lapis)}
.doc-page strong{color:var(--ink)}
.doc-page .cta-row{margin:30px 0 10px}
/* Related links. A pill row rather than a bare list: these are the internal
   links that let a reader (and a crawler) reach the other 20 pages, so they
   have to look like something worth pressing. */
.doc-links{display:flex;flex-wrap:wrap;gap:10px;margin:24px 0 42px;padding:0;list-style:none}
.doc-links li{margin:0;max-width:none}
.doc-links a{display:inline-flex;align-items:center;min-height:44px;font-weight:700;font-size:14px;color:var(--ink);text-decoration:none;border:1px solid var(--hair-2);border-radius:999px;padding:9px 17px;background:var(--card)}
.doc-links a:hover{border-color:var(--lapis);color:var(--lapis)}
/* --copper-on-soft, not --copper-deep: this is small text on the tinted panel,
   where the brand copper measures 4.31 and the body floor is 4.5. */
.doc-note{background:var(--copper-soft);border:1px solid #EBD9B8;border-radius:12px;padding:16px 20px;margin:24px 0}
.doc-note p{color:var(--copper-on-soft);margin:0}
.doc-note p+p{margin-top:10px}
.doc-note ul.creds{margin:12px 0 0;padding-left:21px;list-style:disc}
.doc-note ul.creds li{color:var(--copper-on-soft);margin-bottom:6px;max-width:none}
.doc-note ul.creds li:last-child{margin-bottom:0}
.doc-note ul.creds li::marker{color:var(--copper)}
.doc-note ul.creds b{font-weight:800}
.doc-note ul.creds span{font:600 14.5px/1.6 var(--fig);font-variant-numeric:tabular-nums;color:var(--ink);word-break:break-word}
.doc-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:16px;margin:22px 0 8px}
.doc-card{background:var(--card);border:1px solid var(--hair);border-radius:var(--r);padding:20px 22px}
.doc-card h3{margin:0 0 6px}
.doc-card p{margin:0;font-size:14.5px}
.doc-card a{font-weight:700;text-decoration:none}
.doc-card a:hover{text-decoration:underline}
.updates{margin-top:8px}
.upd-list{display:grid;gap:14px;max-width:900px;margin-top:22px}
.upd{background:var(--card);border:1px solid var(--hair);border-radius:var(--r);box-shadow:var(--shadow);padding:24px 26px;
  display:grid;grid-template-columns:132px 1fr;gap:22px;align-items:start}
.upd.no-photo{grid-template-columns:1fr}
/* THE PHOTOGRAPH'S FRAME, and the picture moves inside it. The frame is what
   keeps its size when the trustee zooms or drags: since 2026-09-05 the picture
   carries object-fit, object-position and a scale of its own, and an <img>
   that was itself the 132px box could not have been moved inside anything. */
.upd-shot{display:block;width:132px;height:132px;overflow:hidden;border-radius:var(--r-s);border:1px solid var(--hair);background:var(--paper)}
.upd-shot img{width:100%;height:100%;display:block}
.upd time{display:inline-block;font:500 13px/1 var(--mono);color:var(--copper-deep);background:var(--copper-soft);
  border-radius:999px;padding:6px 12px;margin-bottom:10px}
.upd h3{font-size:19px;margin-bottom:8px}
.upd p{color:var(--slate);font-size:15px;line-height:1.75;white-space:pre-line}
.upd-empty{background:var(--card);border:1px dashed var(--hair-2);border-radius:var(--r);padding:30px 26px;
  color:var(--slate);font-size:15px;max-width:900px;margin-top:22px}
/* count chip on the homepage card, next to the share row */
.upd-count{font:700 12.5px/1 var(--body);color:var(--lapis);text-decoration:none;border-bottom:1px solid var(--lapis-soft);padding-bottom:2px}
.upd-count:hover{border-bottom-color:var(--lapis)}
/* The footer's 104px lead-in is built for the homepage, where the section above
   it is white. A need page ends on the tinted updates band, so that margin
   showed as a dead white strip; here the tint runs straight into the footer. */
body.on-need footer{margin-top:0}
body.on-doc footer{margin-top:0}
.need-more{margin-top:18px}
.need-more a{font:600 14px/1.6 var(--body);color:var(--lapis);text-decoration:none}
.need-more a:hover{text-decoration:underline}

/* ---------- sticky donate bar (phones and tablets) ---------- */
/* The desktop nav carries a Donate button at all times; below 1020px that nav
   collapses into the hamburger and the only way to give is to find the section.
   This is that button, put back where the thumb already is. */
.dock{position:fixed;left:0;right:0;bottom:0;z-index:47;display:none;
  background:rgba(253,253,251,.94);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-top:1px solid var(--hair);box-shadow:0 -6px 26px rgba(18,22,46,.10);
  padding:10px 16px;padding-bottom:calc(10px + env(safe-area-inset-bottom));
  transform:translateY(120%);transition:transform .3s var(--ease)}
.dock.show{transform:none}
.dock-in{display:flex;align-items:center;gap:14px;max-width:var(--maxw);margin:0 auto}
.dock-txt{min-width:0}
.dock-txt b{display:block;font:800 14.5px/1.35 var(--body);color:var(--ink)}
.dock-txt span{display:block;font:600 13px/1.45 var(--body);color:var(--slate)}
/* min-height, not padding: .btn sets line-height 1, so padding alone left this
   at 38px on a phone — under the 44px a thumb needs. */
.dock .btn{margin-left:auto;flex:none;padding:13px 24px;font-size:14.5px;min-height:44px}
/* the WhatsApp button steps up so the bar never lands on top of it */
.wa-fab{transition:transform .2s var(--ease),bottom .3s var(--ease)}
body.dock-on .wa-fab{bottom:calc(22px + 66px)}
@media print{.dock{display:none!important}}

/* ---------- footer ---------- */
footer{background:var(--lapis-deep);color:#D8DDF5;padding:76px 0 40px;margin-top:104px}
.foot-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr 1.3fr;gap:40px;margin-bottom:52px}
.foot-grid h4{font:800 11px/1 var(--body);letter-spacing:.2em;text-transform:uppercase;color:#8E99D8;margin-bottom:18px}
.foot-grid ul{list-style:none;display:flex;flex-direction:column;gap:10px}
.foot-grid a{color:#C4CBEE;text-decoration:none;font-size:15px}
.foot-grid a:hover{color:#fff}
.foot-brand .brand{color:#fff}
.foot-brand .brand small{color:#C9A265}
.foot-brand p{color:#AAB3E2;font-size:14.5px;max-width:34ch;margin-top:16px}
.foot-grid address{font-style:normal;color:#AAB3E2;font-size:14.5px;line-height:1.8}
.foot-reg{border-block:1px solid rgba(216,221,245,.16);padding:18px 0;display:flex;flex-wrap:wrap;gap:8px 32px;margin-bottom:26px}
.foot-reg span{font:600 13px/1.7 var(--fig);font-variant-numeric:tabular-nums;color:#AAB3E2}
.foot-reg b{font:800 11px/1 var(--body);letter-spacing:.13em;text-transform:uppercase;color:#C9A265;margin-right:8px}
.foot-base{display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px;font-size:14px;color:#8E99D8}

/* ---------- reveal & motion ---------- */
.rv{opacity:0;transform:translateY(16px);transition:opacity .7s var(--ease),transform .7s var(--ease)}
.rv.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .chip-open::before{animation:none}
  .cause::before{transform:scaleX(1)}
  .cause::after,.cause .n{transition:none}
  .cause:hover{transform:none}
  .rv,.hero-art img{opacity:1;transform:none;transition:none}
  .btn:hover,.cause:hover{transform:none}
  .bar i{transition:none}
}

/* ---------- responsive ---------- */
@media (max-width:1020px){
  .nav-links{display:none}
  /* 28px of gap was written for a desktop bar with room to spare. On a phone it
     is the reason the three things on the bar had to fight for the width. */
  .nav-in{gap:12px;padding:12px 16px}
  /* The wordmark is not a shrinkable box: at 320px the flex algorithm squeezed
     it from 134px to 97px and the small caps line broke. */
  .brand{flex:none}
  .menu-btn{display:block;margin-left:0}
  /* Get Help stays on the bar when the rest of the navigation folds away.
     WHITE-SPACE AND FLEX:NONE ARE THE POINT. Without them this pill was the
     only thing on the bar that could give way, so it shrank below its own
     words and broke "Get Help" onto two lines, which is what the owner
     photographed on 2026-08-29. A button that cannot fit must make the bar
     tighter, never fold its own label. */
  .nav-help-m{display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;flex:none;
    margin-left:auto;font:800 13.5px/1 var(--body);
    color:var(--ink);text-decoration:none;border:1.5px solid var(--ink);border-radius:999px;padding:11px 16px;min-height:44px}
  .csr-band{grid-template-columns:1fr;padding:38px 30px}
  .hero{padding-top:104px}
  .hero-grid{grid-template-columns:1fr;gap:18px}
  /* phones: compact, perfectly centred bird with the halo hugging it */
  .hero-art{order:-1;width:-moz-fit-content;width:fit-content;margin:0 auto}
  .hero-art img{width:min(240px,58vw)}
  .hero-art video{width:min(420px,100vw)}
  .snd{right:auto;left:50%;transform:translateX(-50%);bottom:-6%;padding:8px 14px 8px 11px;font-size:12px}
  .snd:hover{transform:translateX(-50%) translateY(-2px)}
  .hero-art .halo{inset:4% -10%}
  .hero-badge{margin-bottom:20px}
  .registry ul{grid-template-columns:1fr 1fr}
  .registry li:last-child{grid-column:1/-1}
  /* minmax(0,1fr), not 1fr: a bare 1fr track is minmax(auto,1fr) and refuses to
     shrink below its content's min-content width, so a long unbroken string blew
     these tracks wider than the phone and .proj clipped the overhang away. */
  .creed-band,.donate-grid,.proj-top,.people{grid-template-columns:minmax(0,1fr)}
  /* THE NEED PAGE ON A PHONE: option C2. The blue column dissolves so the
     photograph and the panel become ordinary rows, and the photograph is
     lifted above the title. Every block returns to automatic placement first,
     or the explicit rows above would hold the laptop's order and the order
     property would be ignored. */
  .proj.np{grid-template-columns:minmax(0,1fr);grid-template-rows:none}
  /* Named one by one, not `.proj.np>*`: the laptop rules place these blocks by
     class, so a wildcard reset is LESS specific than the thing it is trying to
     undo and the story and the strip keep their rows while everything else
     floats. That defect looked exactly like the order property being ignored. */
  .proj.np>.proj-info,.proj.np>.np-money,.proj.np>.np-right,.proj.np>.ptl{grid-column:1;grid-row:auto}
  .proj.np .np-right{display:contents}
  /* ON A PHONE THE PHOTOGRAPH IS THE CARD'S OWN TOP, WITH NO MAT.
     Owner, 2026-09-05, two photographs from his phone minutes apart: the
     /needs/ card, full width against the paper, *"for mobile, this looks
     good"*, and this page with the blue mount around it, *"for mobile, this
     photo and blue background does not suit"*. He is right: on a laptop the
     mount sits INSIDE a blue column and belongs to it, and on a phone that
     column is gone, so the mount was a blue band with nothing to belong to.
     The card's own overflow:hidden rounds the top corners, and the letterbox
     of a picture shown WHOLE falls on the paper, exactly as it does on the
     needs grid. */
  .proj.np .np-lead{order:0;padding:0;background:var(--card)}
  .proj.np .np-lead figure{border-radius:0;box-shadow:none;background:var(--card)}
  .proj.np>.proj-info{order:1}
  .proj.np .np-money{order:2}
  .proj.np .proj-aside{order:3}
  .proj.np>.ptl{order:4}
  /* AND THE HOMEPAGE CARD DOES THE SAME on a phone: the blue column dissolves,
     so the photograph and the panel become ordinary rows of `.proj-top` and the
     photograph is lifted above the chips and the title. `display:contents`
     hands its two children to the grid, which is what makes `order` reach them
     at all. The mount goes with it, for the reason it goes on the need page:
     on a phone there is no blue column for a mount to belong to. */
  .proj-top>.np-right{display:contents}
  .proj-top>.np-right>.np-lead{order:0;padding:0;background:var(--card)}
  .proj-top>.np-right>.np-lead figure{border-radius:0;box-shadow:none;background:var(--card)}
  .proj-top>.proj-info{order:1}
  .proj-top>.np-right>.proj-aside{order:2}
  .cause-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* THE ODD CARD OUT TAKES THE WHOLE ROW. Owner, 2026-08-30: "9th can be a one
     column". Nine cards two up leaves the ninth alone beside an empty half, and
     the app has never had that hole: its cells are flexBasis 47% with
     flexGrow 1, so a lone last card grows to the full width by itself. Same
     idiom as .registry li:last-child above. Guarded in
     tests/phone-alignment.browser.mjs. */
  .cause-grid>.cause:last-child:nth-child(odd){grid-column:1/-1}
  .fy{grid-template-columns:minmax(0,1fr)}
  .proj-aside{padding:36px}
  .foot-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:34px}
  /* exactly where the nav's Donate button stops being visible */
  .dock{display:block}
}
@media (max-width:600px){
  /* Everything on the top bar steps down together so that a 320px phone holds
     the wordmark, the Get Help pill and the menu button on one line, each at
     its full width. Measured, not assumed: tests/pages.browser.mjs. */
  .nav-in{gap:10px;padding:10px 14px}
  .brand{gap:9px}
  .brand img{width:36px;height:36px}
  .brand b{font-size:17px}
  .brand small{font-size:8.5px;letter-spacing:.2em}
  .nav-help-m{font-size:12.5px;padding:11px 13px}
  /* THE DOCK IS FIXED, SO THE MENU HAS TO KNOW IT IS THERE.
     Owner's own screenshot, 2026-08-29: the menu open on the homepage, with
     "Privacy Policy" cut in half by the donate bar sitting on top of it. The
     menu scrolls, so the fix is room at the bottom of its scroll, not a
     shorter list: 66px is the dock, 24px is the padding it already had. */
  .mobile-menu{padding:76px 18px 24px}
  body.dock-on .mobile-menu{padding-bottom:90px}
  /* THE CAUSE GRID STAYS AT TWO COLUMNS ON A PHONE.
     Owner, 2026-08-29, at 400px: "on mobile this should be two column right,
     why so many differences". The app shows nine cause cards two up and the
     website was dropping to one, so the same nine causes were a short grid on
     one screen and a long scroll on the other. The compact card below (smaller
     ghost numeral, 18px heading, tighter copy) was already written for two
     columns. Only the form grid collapses here. */
  .fgrid{grid-template-columns:minmax(0,1fr)}
  section.block{padding:68px 0}
  .proj-info,.ptl,.np-money{padding-inline:20px}
  /* THE TWO HALVES OF ONE CARD START AT THE SAME LEFT EDGE.
     .proj-info came down to 20px on a phone and the navy panel below it kept
     its desktop 42px, so the need's story and the panel explaining its money
     were indented differently inside the same card. */
  .proj-aside{padding:26px 20px;gap:20px}
  /* Two chips that cannot share a line stack, and an 18px bottom margin on
     each opened a hole between them. The gap belongs BETWEEN the chips and
     the heading, once. */
  .proj-info .chip{margin:0 8px 8px 0}
  .proj-info h3,.proj-info h1{margin-top:10px}
  /* The location is an area, and areas are long: "G N Mills · Coimbatore
     District · Tamil Nadu" at a fixed 14px ran past the card and under the
     WhatsApp button on the owner's phone. It is sized to the viewport, like
     every other value on this card. */
  .proj-info .loc{font-size:clamp(11.5px,3.4vw,14px);margin-bottom:14px}
  /* Funded and Due date are ONE line, the way the app shows them. */
  .due{font-size:clamp(10px,2.85vw,14px);gap:6px 14px;flex-wrap:nowrap;margin-bottom:20px}
  .due>span{white-space:nowrap}
  .people-card .sub .nb{white-space:nowrap}
  /* 44px IS THE FLOOR, AND A PHONE IS WHERE IT MATTERS.
     These were shrunk to 37px to fit the row and that is the wrong trade: the
     row wraps, a thumb does not. Measured at 320, the label and four 44px
     circles still fit on one line. */
  .sh{width:44px;height:44px}
  .sh svg{width:19px;height:19px}
  .needs-btn{width:44px;height:44px}
  .snd{min-height:44px;padding:12px 16px 12px 13px}
  /* A 9px dot is a target nobody can hit. The DOT is unchanged and drawn by a
     pseudo element; the button around it grows to 44px and stays invisible.
     background-clip:content-box was the first attempt and it cannot work: the
     radius belongs to the border box, so the painted content box came out a
     9px SQUARE. */
  .needs-dot{width:22px;height:44px;background:none;position:relative}
  .needs-dot::before{content:"";position:absolute;left:50%;top:50%;
    transform:translate(-50%,-50%);width:9px;height:9px;border-radius:50%;
    background:var(--hair-2);transition:background .25s var(--ease),width .25s var(--ease)}
  .needs-dot.on{width:32px;background:none}
  .needs-dot.on::before{background:linear-gradient(90deg,var(--copper),var(--lapis));
    width:26px;border-radius:999px}
  .needs-dots{gap:2px}
  .pay-card,.dform{padding:28px 22px}
  /* THE TWO WAYS TO GIVE ARE A CHOICE, NOT A RAGGED EDGE.
     They are the same decision, so they get the same width: side by side they
     sat at 178px and 152px, left aligned under a full-width form, which read
     as two odd shapes rather than two options. Full width, stacked, in the
     order the page recommends them. */
  .dform-actions{flex-direction:column;align-items:stretch;gap:10px}
  .dform-actions .btn{width:100%;justify-content:center}
  .hero h1{font-size:clamp(38px,11vw,54px)}
  /* CENTRED ON A PHONE, AND ONLY ON A PHONE. Owner, 2026-08-30: "only for
     mobile can we align this text as centre." On a phone the bird sits centred
     above this copy and everything under it started hard against the left
     margin, so the pill, the creed and the lede each began on a different
     optical axis from the art they belong to. On a laptop the art is BESIDE
     the copy, and there left aligned is right: a centred column next to a
     picture has no axis at all. Hence this lives here and nowhere else.
     `max-width` plus auto margins, because the h1 is capped at 14ch and the
     lede at 50ch: text-align alone would centre the words inside a box still
     pinned to the left. */
  .hero-copy{text-align:center}
  .hero-copy .hero-badge{margin-left:auto;margin-right:auto}
  /* THE CREED AND THE LEDE READ LEFT, THE BADGE AND THE BIRD STAY CENTRED.
     Owner, 2026-09-03: "align we chose you and the paragraph content to left.
     Let others be as it is."

     THIS NARROWS THE 2026-08-30 FREEZE, it does not undo it. That decision
     centred the whole hero column on a phone so the pill, the creed and the
     lede shared the bird's optical axis. It was right about the pill and wrong
     about the two blocks of running text: centred prose sets a ragged left
     edge, so every line of a five line lede starts somewhere different and the
     eye has to find the beginning of each one. The app has always set both
     left and reads better for it, which is the sibling rule doing its job.
     A short badge is a shape and centres happily; a paragraph is not. */
  .hero-copy h1,.hero-copy .lede{text-align:left;margin-left:0;margin-right:0}
  /* THE BUTTONS ARE THE APP'S. Owner, same three screenshots: "align buttons
     like app". Side by side they were 430px and 300px, centred, so two equal
     choices read as two different sizes: the same defect the donate form's two
     ways to give had, and the same fix. Full width, stacked, in the page's
     recommended order, with a declared gap. */
  .hero-copy .cta-row{flex-direction:column;align-items:stretch;gap:10px}
  .hero-copy .cta-row .btn{width:100%;justify-content:center}
  .hero-stats{display:grid;grid-template-columns:1fr 1fr;gap:20px 16px}
  /* ONE LINE ON A PHONE, AND THE THIRD CLAIM IS NOT ON IT.
     Owner, 2026-08-29: "just remove serving across India so just Registered
     charitable trust and 80G tax benefit stays in one line for mobile."
     Stacking the three claims fixed the orphan separator and was not what he
     wanted. Two claims, nowrap, and the type sized so they fit from 320 up.
     "Serving across India" stays on the desktop bar and everywhere else. */
  .hero-badge{display:inline-flex;align-items:center;gap:7px;white-space:nowrap;
    font-size:clamp(10.5px,3.3vw,14px);line-height:1.4;padding:9px 14px 9px 10px}
  .hero-badge .dot{flex:none}
  .hero-badge .bi:last-of-type{display:none}
  .creed-card{padding:28px 24px}
  .creed-card .gl{font-size:38px}
  .docs-reg{grid-template-columns:1fr}
  .fy{padding:22px 20px}
  /* THREE PILLS OF THREE DIFFERENT WIDTHS ARE NOT A LIST, THEY ARE A RAGGED
     EDGE. Income Tax Return, Audited P&L and Balance Sheet each shrank to
     their own text, so the three status chips beside them landed at three
     different places down the card while the Registrations card directly
     below lined its own up perfectly. One row each, label left, status flush
     right, the same shape as .docs-reg. */
     THE REGISTRATIONS CARD IS ALSO A .docs, so this is scoped away from it:
     `<div class="docs docs-reg">` carries both classes, and an unscoped
     `.docs .doc` has the same specificity as `.docs-reg .doc` but comes later
     in the file, so it silently turned that two-row grid into a flex row and
     pushed the page 44px sideways at 320. */
  .docs:not(.docs-reg){display:grid;grid-template-columns:1fr;gap:8px}
  .docs:not(.docs-reg) .doc{display:flex;justify-content:space-between;
    align-items:center;gap:12px;width:100%;border-radius:14px;padding:12px 16px;min-height:44px}
  .docs:not(.docs-reg) .doc .st{flex:none}

  /* Compact cause cards, because the phone shows the same nine two up.
     A CARD IS overflow:hidden, SO A WORD TOO WIDE FOR IT IS CUT WITHOUT A
     SOUND: at 360px "Empowerment" wanted 129px in a 111px card and the last
     letters simply were not there. Nothing measures that - the overflow rule
     exempts anything inside an overflow:hidden box, and the clipped-label rule
     only sees a label told not to wrap. So the type steps down, the padding
     tightens, and hyphens plus overflow-wrap mean the longest word in the copy
     BREAKS instead of disappearing. */
  .cause-grid{gap:10px}
  .cause{padding:18px 15px}
  /* THE NUMERAL COMES OUT FROM BEHIND THE WORDS AND STANDS ABOVE THEM.
     Owner, 2026-08-29: the app "seems to be so beautiful while the web is
     worst", and this card is the clearest reason why. Two up on a phone the
     heading always reaches the numeral: measured at 320, 360 and 390, all nine
     headings overlapped it by 28-38px horizontally and 26px vertically, so
     "Disaster Relief" was printed straight through "08" and "Livelihood &"
     through "09". Fading it to .05 made it fainter, not absent, and a heading
     over a ghost is still a heading over a ghost.
     The app never had this: its numeral is a real element ABOVE the heading,
     in the flow, with the card's own width to itself. So is this one now.
     Nothing can collide with a box that is laid out rather than floated. */
  .cause .n{position:static;display:block;font-size:26px;opacity:.28;
    color:var(--lapis);margin-bottom:10px;letter-spacing:-.02em}
  .cause:hover .n{opacity:.4;transform:none}
  /* The type is sized so the LONGEST WORD fits the card it is in, at every
     width from 320 up: "Empowerment", "Self-Reliance", "self-employment".
     A fixed size fitted at 390 and broke "Empowermen / t" at 360 with no
     hyphen, because Chrome only hyphenates where it has a dictionary and
     overflow-wrap gets there first. So the clamp does the work, and
     hyphens plus overflow-wrap are the net underneath that should never
     be needed. */
  .cause h3{font-size:clamp(13px,4.3vw,17px);margin:0 0 8px;max-width:none;hyphens:auto;overflow-wrap:break-word}
  .cause h3::after{margin-top:9px}
  .cause p{font-size:clamp(12.5px,3.9vw,13.5px);line-height:1.6;overflow-wrap:break-word}
  /* Sized like the copy it follows so it is never the widest thing in a
     145px card, and the same floor rule applies at every width. */
  .cause .more{padding-top:12px;font-size:clamp(12px,3.7vw,13.5px);gap:5px}

  .cause:hover{transform:none}
  /* footer credentials: one aligned row per registration */
  .foot-reg{display:grid;grid-template-columns:1fr;gap:9px;padding:16px 0}
  .foot-reg b{display:inline-block;min-width:84px}
  .vault-note{padding:16px 18px}
  /* A DESKTOP BAND'S BREATHING ROOM IS A PHONE'S EMPTY SCREEN.
     Owner, 2026-08-29, on the donate screen: the last sentence ended and then
     172px of blank cream ran before the navy started, which is half a phone of
     nothing. It was the section's own 68px bottom padding plus footer
     margin-top:104px, a figure chosen for a wide layout where the footer is a
     band under a grid. The section padding is already the separation here. */
  footer{margin-top:0;padding:52px 0 32px}
  .foot-grid{grid-template-columns:1fr;gap:30px;margin-bottom:34px}
  .foot-base{flex-direction:column;align-items:flex-start}
  /* A VALUE AND ITS COPY BUTTON CANNOT SHARE A LINE ON A PHONE. At 320px the
     flex row left the value an 84px box, so even "Alorah Foundation" wrapped,
     and a 28 character UPI id broke mid-token at every phone width. The button
     steps underneath, the value gets the whole row, and the size scales so the
     longest id on the page stays on one line from 320 up. */
  .field-row{flex-wrap:wrap;gap:8px 10px;padding:9px 11px}
  /* No min-width:0 on purpose. The row keeps the button beside a short value
     and drops it underneath only where the value needs the whole width, which
     on a phone is the 28 character UPI id and nothing else. */
  .field-row>div{flex:1 1 auto}
  .field-row .copy{margin-left:auto;min-height:44px;padding:10px 16px}
  .field-row div span{font-size:clamp(11.5px,3.6vw,14px)}
  .registry ul{grid-template-columns:1fr 1fr;gap:12px;padding:18px 16px}
  .registry li{padding:11px 12px}
  /* sized so the longest registration number on the page fits its card at
     320px and up, instead of wrapping onto a second line */
  .registry li span{font-size:clamp(10.5px,3.2vw,13.5px)}
  .registry li b{font-size:10px;letter-spacing:.1em}
  .ledger-row div{padding:12px 5px}
  .ledger b{font-size:clamp(11.5px,3.3vw,17px)}
  .ledger span{letter-spacing:.06em;font-size:9.5px;line-height:1.6}
  /* QR stacks above its caption rather than squeezing both onto one line */
  .upi-qr{flex-direction:column;align-items:flex-start;gap:14px}
  .pay-choice{grid-template-columns:minmax(0,1fr)}
  /* On a phone the code is the SECOND thing: the UPI button above it is what
     that donor will actually use, and the code is there to be shown to
     somebody else paying on their behalf. */
  .qr-panel{padding:18px}
  .qr-panel .qr-in{flex-direction:column;align-items:stretch;gap:18px}
  .qr-panel img{order:2;align-self:center;width:min(220px,100%);height:auto;aspect-ratio:1}
  .qr-side{order:1}
  .need-page{padding-top:104px}
  .doc-page{padding-top:104px}
  .upd{grid-template-columns:1fr;gap:16px;padding:22px 20px}
  .upd-shot{width:100%;height:auto;aspect-ratio:4/3;max-height:260px}
  .faq summary{padding:15px 18px;font-size:15px;gap:12px}
  .faq .a{padding:0 18px 18px;font-size:14.5px}
  .dock{padding-inline:14px}
  .dock .btn{padding:12px 20px;min-height:44px}
}
/* THREE LAKH-SCALE FIGURES DO FIT ACROSS A PHONE, and the app proves it.
   Until 2026-08-29 this stacked below 430px, which is every phone in the
   house: 360, 390 and 412 all got three rows of value-then-label while the
   app showed the same need three up, and that difference is most of why the
   owner called the app beautiful and the web worst. The app fits them by
   shrinking the figure (adjustsFontSizeToFit, minimumFontScale .7); CSS has no
   such thing, so the size is clamped to the viewport instead and the cell
   padding is tight enough that a lakh-scale figure still has room.
   Only below 360px does it give up and stack. Verified against a ₹45,00,000
   fixture at 320/360/390/412 by tests/need-verify.browser.mjs, which measures
   the text against the CLIPPING box.

   The original note, still true and still the reason the guard exists:

   Found 2026-08-28 while building the verification stamp, by rendering a
   ₹4,50,000 need: "Still needed", the number a donor actually acts on, was cut
   by 76px at 320 and by 6px at 390. It had been that way all along and nothing
   caught it, because .ledger sets overflow:hidden. The page therefore does not
   scroll sideways and nothing crosses the viewport edge, which is all the two
   existing sweeps look for, and the only live need is ₹50,000, which fits.
   A figure can be cut in half without a single one of those alarms sounding.
   tests/need-verify.browser.mjs measures the text against the clipping box. */
/* FOUR FIGURES DO NOT FIT ACROSS A PHONE, so on a phone they are two and two.
   Found 2026-09-05 by the layout guard the moment the fourth figure existed:
   at 360 and 390 the cells were 39px and 48px wide for labels that wanted 68px
   and 69px, and "Still needed" and "Given so far" were both cut. The frozen
   2026-08-29 rule is about the THREE column ledger and is untouched: a need
   with nothing given still has three columns from 360 up. This is what the
   fourth does instead of squeezing them all onto one line.
   The dividers are redrawn for a grid rather than a row: a border-left on every
   cell but the first draws a line down the middle of nothing once the cells
   wrap. */
@media (min-width:360px) and (max-width:479px){
  .ledger-row.four{grid-template-columns:repeat(2,minmax(0,1fr))}
  .ledger-row.four div{border-left:0;border-top:1px solid var(--hair)}
  .ledger-row.four div:nth-child(2n){border-left:1px solid var(--hair)}
  .ledger-row.four div:nth-child(-n+2){border-top:0}
}

@media (max-width:359px){
  .ledger-row,.ledger-row.four{grid-template-columns:minmax(0,1fr)}
  /* LABEL LEADS, FIGURE CLOSES, exactly as the panel beside it does.
     Owner, 2026-08-29: "align amounts properly". That rule was written for
     .pa-split and this row was left printing the value first and the label
     last, so one need showed a donor two money panels in opposite orders on
     the same screen. The label takes the slack, the figure is flush right,
     and three amounts of different widths read down one straight edge. */
  .ledger-row div{display:flex;align-items:baseline;justify-content:space-between;gap:14px;padding:11px 14px}
  .ledger-row div+div{border-left:0;border-top:1px solid var(--hair)}
  .ledger span{order:1;flex:1;min-width:0;line-height:1.4}
  .ledger b{order:2;flex:none;display:block;font-size:17px;text-align:right}
}
/* Small phones: the bar keeps the button and the promise, drops the second line
   rather than wrapping the whole bar onto two rows. */
@media (max-width:380px){
  .dock-txt span{display:none}
  .dock-txt b{font-size:13.5px}
  .dock .btn{padding:12px 18px;font-size:14px;min-height:44px}
  .share{gap:6px}
}
