/*
 * Dan Noy-Dhar — website design system.
 *
 * Same brand tokens as the two Flutter apps, so the site and the apps read as
 * one organisation. Written as plain CSS with no build step and no framework:
 * this has to load fast on a cheap Android over 3G in Savar, which is the
 * actual constraint that shaped every decision here.
 */

:root {
  /* Brand. Red and white, with the flag green where a third colour is needed. */
  --red: #e72240;
  --red-dark: #a8122c;
  --red-tint: #fdeaed;
  --green: #006a4e;
  --green-tint: #e4f2ec;
  --amber: #b87a1c;
  --amber-tint: #fdf3e2;

  --ink: #1a1618;
  --ink-2: #4a4247;
  --ink-3: #7c7278;
  --line: #e8e2e4;
  --bg: #ffffff;
  --bg-2: #faf7f8;
  --card: #ffffff;

  --radius: 14px;
  --radius-sm: 9px;
  --shadow: 0 1px 2px rgba(26, 22, 24, .04), 0 8px 24px rgba(26, 22, 24, .06);
  --wrap: 1120px;

  --font-latin: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-bn: 'Noto Sans Bengali', 'Nirmala UI', 'Kalpurush', sans-serif;
}

/* Bengali needs more leading than Latin — vowel signs sit above and below. */
html[lang='bn'] body { font-family: var(--font-bn); line-height: 1.85; }
html[lang='en'] body { font-family: var(--font-latin); line-height: 1.65; }

*, *::before, *::after { box-sizing: border-box; }

/* `hidden` means hidden, whatever else the element is told to be.
   The browser's own rule for it is `[hidden] { display: none }`, which any
   class selector outranks — so `.feedback-form { display: flex }` quietly beat
   it and the form sat open on the page before anybody pressed the button.
   Anything that sets `display` on a component has the same problem, so this is
   stated once, here, rather than patched per component. */
[hidden] { display: none !important; }

body {
  margin: 0;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  font-size: 16px;
}

h1, h2, h3, h4 { line-height: 1.3; margin: 0 0 .5em; font-weight: 700; }
h1 { font-size: clamp(1.9rem, 1.2rem + 2.6vw, 3rem); letter-spacing: -.02em; }
h2 { font-size: clamp(1.4rem, 1.1rem + 1.3vw, 2rem); letter-spacing: -.01em; }
h3 { font-size: 1.15rem; }
p { margin: 0 0 1em; }
a { color: var(--red); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--red-dark); }
img { max-width: 100%; height: auto; display: block; }

.wrap { width: min(100% - 2.5rem, var(--wrap)); margin-inline: auto; }
.muted { color: var(--ink-3); }
.center { text-align: center; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--red); color: #fff; padding: .7rem 1.1rem;
}
.skip:focus { left: .5rem; top: .5rem; }

/* Focus ring — visible, brand-coloured, never removed. */
:focus-visible { outline: 3px solid var(--red); outline-offset: 2px; border-radius: 4px; }

/* ---------------------------------------------------------------- header */

.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255, 255, 255, .92);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}
/* Two rows: who we are and what you can do, then where you can go.
   Thirteen controls never fitted on one line — the last nav link used to drop
   onto a second line by itself, which reads as a broken menu.

   The narrow layout is the base and the wide one is the override, so a phone
   parses the fewest rules. */
.header-in { display: flex; flex-direction: column; gap: .35rem; padding: .45rem 0; }
.header-top { display: flex; align-items: center; gap: 1rem; }

/* Wide screens: the mark and the name sit at the left across the full height,
   with the buttons above the menu on the right.

      ┌──────────┐   [f] [f+] Contribute  Apply  বাংলা
      │  দান নয়  │   Home  About Us  Fund  Contributors …
      └──────────┘

   A grid rather than more nesting, and `display: contents` on the inner row so
   the brand and the buttons become grid items directly. That keeps one set of
   markup for both layouts — the alternative is a second copy of the header for
   desktop, which is a second copy to keep in step. */
@media (min-width: 941px) {
  .header-in {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-rows: auto auto;
    align-items: center;
    column-gap: 1.5rem;
    row-gap: .3rem;
  }
  .header-top { display: contents; }
  .brand { grid-column: 1; grid-row: 1 / span 2; align-self: stretch; }
  .header-actions { grid-column: 2; grid-row: 1; justify-self: end; }
  .nav { grid-column: 2; grid-row: 2; justify-self: end; }

  /* Sized to fill the two rows it spans, rather than floating in the middle of
     them with empty space above and below.

     A fixed height rather than `height: 100%`: the brand is a spanning grid
     item, so it feeds back into how tall the rows are — a logo measured from
     the row height would grow the row, which would grow the logo. The number
     is the two rows plus the gap between them, which is what the buttons and
     the menu actually come to. */
  .brand img { width: 74px; height: 74px; border-radius: 15px; }
  .brand-text { font-size: 1.45rem; }
  .brand-sub { font-size: .78rem; margin-top: .18rem; }
  html[lang='bn'] .brand-sub { font-size: .88rem; }
}
.brand { display: flex; align-items: center; gap: .7rem; text-decoration: none; color: var(--ink); flex: 0 0 auto; }
.brand img { width: 54px; height: 54px; border-radius: 12px; }

/* The name and the motto are one block, set tight.
   They sat apart because the `<br>` between them inherited the body's 1.65
   line height — which is right for paragraphs and far too loose for two lines
   that should read as a single mark. */
.brand > span { display: block; line-height: 1.12; }
.brand-text { font-weight: 800; font-size: 1.24rem; letter-spacing: -.015em; }
.brand-sub {
  display: block; margin-top: .1rem;
  font-size: .72rem; color: var(--ink-3); font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
}
/* Bengali has no letter case, and tracking pushes its conjuncts apart, so the
   motto is set plainly there — সুদ ছাড়া ধার, not a spaced-out approximation. */
html[lang='bn'] .brand-sub {
  text-transform: none; letter-spacing: 0; font-size: .8rem;
}

/* Its own row now, so it neither competes with the buttons for width nor
   wraps. On a narrow screen it scrolls sideways rather than reflowing — a menu
   that changes height as you translate the page moves everything under the
   reader's thumb. */
.nav {
  display: flex; gap: .15rem;
  overflow-x: auto; scrollbar-width: none;
  padding-bottom: .1rem;
}
.nav::-webkit-scrollbar { display: none; }
.nav a {
  padding: .45rem .7rem; border-radius: var(--radius-sm);
  text-decoration: none; color: var(--ink-2); font-weight: 600; font-size: .93rem;
  white-space: nowrap;
}
.nav a:hover { background: var(--bg-2); color: var(--ink); }
.nav a[aria-current='page'] { color: var(--red); background: var(--red-tint); }

/* Two rows: the icon links above, the named buttons below with the language
   switch at the far end. Right-aligned so the whole stack sits against the
   edge of the header rather than drifting under the navigation. */
/* One row, pushed to the end, with the language switch last: it is the control
   somebody uses once and then never again, so it should be findable and never
   in the way of the call to action. */
.header-actions {
  display: flex; align-items: center; gap: .5rem;
  margin-inline-start: auto; flex: 0 0 auto;
}
/* Pushed to the end of its row, and kept there in Bengali too: a logical
   property rather than margin-left, since the site sets dir per page. */
.header-row .lang-btn { margin-inline-start: .35rem; }
.nav-toggle { display: none; background: none; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .45rem .6rem; cursor: pointer; }

@media (max-width: 940px) {
  .nav-toggle { display: block; }
  .nav {
    display: none; position: absolute; inset-inline: 0; top: 100%;
    background: #fff; border-bottom: 1px solid var(--line);
    flex-direction: column; padding: .5rem 1.25rem 1rem;
  }
  .nav.open { display: flex; }
  .nav a { padding: .7rem .5rem; }
}

/* Phone and small tablet — wherever the menu has collapsed to a button.

   The five buttons do not fit beside the brand at these widths, so the header
   stacks: actions across the top, then the organisation's name and the menu
   button facing each other on the line below.

      row 1                    [f] [f+] Contribute  Apply  বাংলা
      row 2   [logo] Dan Noy-Dhar                             ☰

   Reordered with flexbox rather than by moving the markup, so one header
   serves both layouts and there is no second copy to keep in step. The visual
   order matches the reading order either way, so nothing is lost to somebody
   navigating by keyboard. */
@media (max-width: 940px) {
  .header-top { flex-wrap: wrap; row-gap: .55rem; gap: .5rem; }
  .header-actions {
    order: -1;
    width: 100%; margin-inline-start: 0;
    justify-content: flex-end; flex-wrap: wrap;
  }
  .brand { order: 1; }
  .nav-toggle { order: 2; margin-inline-start: auto; }
}

/* ---------------------------------------------------------------- buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .72rem 1.25rem; border-radius: var(--radius-sm);
  font-weight: 700; font-size: .95rem; text-decoration: none;
  border: 1px solid transparent; cursor: pointer; transition: transform .12s ease, background .15s ease;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--red); color: #fff; }
.btn-primary:hover { background: var(--red-dark); color: #fff; }
.btn-ghost { background: #fff; color: var(--ink); border-color: var(--line); }
.btn-ghost:hover { background: var(--bg-2); color: var(--ink); }
.btn-sm { padding: .45rem .8rem; font-size: .85rem; }
.lang-btn { font-weight: 700; font-size: .85rem; }

/* ---------------------------------------------------------------- hero */

.hero { padding: clamp(2.5rem, 5vw, 4.5rem) 0 2rem; background:
  radial-gradient(1000px 380px at 12% -10%, var(--red-tint), transparent 65%),
  radial-gradient(760px 320px at 92% 0%, var(--green-tint), transparent 60%); }
/* The banner is 1354×612 — more than twice as wide as it is tall — so it gets
   the larger share. The old split gave the art the narrow column, which was
   right for a square logo and would squeeze this to a strip. */
.hero-grid { display: grid; grid-template-columns: 1fr 1.15fr; gap: 2.5rem; align-items: center; }
@media (max-width: 860px) { .hero-grid { grid-template-columns: 1fr; } }
.hero p.lead { font-size: 1.08rem; color: var(--ink-2); max-width: 56ch; }
.hero-cta { display: flex; gap: .7rem; flex-wrap: wrap; margin-top: 1.4rem; }
.hero-art { justify-self: center; max-width: 320px; border-radius: 22px; box-shadow: var(--shadow); }

.eyebrow {
  display: inline-flex; align-items: center; gap: .45rem;
  background: #fff; border: 1px solid var(--line); color: var(--ink-2);
  padding: .3rem .75rem; border-radius: 999px; font-size: .8rem; font-weight: 700;
  margin-bottom: .9rem;
}
.eyebrow .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--green); }

/* ---------------------------------------------------------------- stats */

/* A seven-figure taka amount is the widest thing this grid ever has to hold.
   `৳18,96,300` is eleven glyphs; at the old 170px track and 1.85rem it did not
   fit, and `overflow: hidden` — needed so the accent stripe respects the
   corner radius — silently sliced the last digit off. A fund summary that
   renders ৳18,96,300 as "৳18,96,30" is worse than no fund summary. */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: .9rem; }

/* Seven figures, laid out four then three, both rows full width.
   `auto-fit` packed five onto the first row and left the last two stranded
   beside a gap half the page wide. Twelve columns divide by both three and
   four, so the two rows can each fill the line: four cards of three columns,
   then three cards of four. */
@media (min-width: 940px) {
  .stat-grid { grid-template-columns: repeat(12, 1fr); }
  .stat-grid > .stat { grid-column: span 3; }
  .stat-grid > .stat:nth-child(n + 5) { grid-column: span 4; }
}
.stat {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.1rem 1.15rem; position: relative; overflow: hidden;
  container-type: inline-size;
}
.stat::after {
  content: ''; position: absolute; inset-block-start: 0; inset-inline-start: 0;
  width: 3px; height: 100%; background: var(--red);
}
.stat.green::after { background: var(--green); }
.stat.amber::after { background: var(--amber); }
.stat-label { font-size: .82rem; color: var(--ink-3); font-weight: 600; margin-bottom: .35rem; }
.stat-value {
  font-family: var(--font-latin); font-size: clamp(1.2rem, 0.85rem + 1.2vw, 1.7rem);
  font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Scales to the tile rather than the viewport, which is what actually
   constrains it — a 1fr track in a six-column grid is narrow on a wide screen
   too, so a viewport-based clamp gets that case exactly backwards. */
@supports (container-type: inline-size) {
  .stat-value { font-size: clamp(1.15rem, 8.5cqi, 1.7rem); }
}
html[lang='bn'] .stat-value { font-family: var(--font-bn); }

.live-badge {
  display: inline-flex; align-items: center; gap: .4rem; font-size: .75rem;
  font-weight: 700; color: var(--green); background: var(--green-tint);
  padding: .22rem .6rem; border-radius: 999px;
}
.live-badge .pulse { width: 6px; height: 6px; border-radius: 50%; background: var(--green); animation: pulse 2s infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }

/* ---------------------------------------------------------------- sections */

.section { padding: clamp(2.2rem, 4vw, 3.6rem) 0; }
.section-alt { background: var(--bg-2); }
.section-head { margin-bottom: 1.6rem; }
.section-head p { color: var(--ink-2); max-width: 62ch; margin: 0; }

.prose { max-width: 72ch; }
/* Justified, the way the printed Bangla these pages came from is set.
   `text-wrap: pretty` is what keeps justification from opening rivers of
   whitespace on a narrow phone; browsers without it fall back to plain
   justification, which is still what was asked for. Hyphens stay off — the
   Bangla text must not be broken mid-word. */
.prose p {
  color: var(--ink-2);
  text-align: justify;
  text-wrap: pretty;
  hyphens: none;
}
.prose h2 { margin-top: 1.8em; }

/* Account details are reference, not prose: left-aligned, never justified,
   and the number stays on one line however narrow the screen gets. */
/* The figures a treasurer counted rather than the ledger derived.
   Marked, not hidden: this page's whole claim is that its numbers come from the
   records, and four that come from somebody's count of a cash box should not
   look identical to the twelve that do not. */
.stat.stated { border-style: dashed; }
.stat.stated .stat-label::after {
  content: '•';
  margin-inline-start: .35rem;
  color: var(--ink-3);
}
.stat-asof { margin: 0 0 .9rem; }
.stat-grid + .stat-asof { margin: .9rem 0 0; }

.bank-panel {
  margin-top: 2.2rem; padding: 1.2rem 1.3rem;
  background: var(--bg-2); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.bank-panel h2 { margin: 0 0 .9rem; font-size: 1.05rem; }
.bank-list { margin: 0; display: grid; gap: .45rem; }
.bank-row { display: flex; flex-wrap: wrap; gap: .2rem .6rem; text-align: start; }
.bank-row dt { color: var(--ink-2); min-width: 11ch; }
.bank-row dd { margin: 0; }
.bank-row dd b { white-space: nowrap; }

.card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1rem; }
.card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.3rem; box-shadow: var(--shadow);
}
.card h3 { margin-bottom: .4rem; }
.card p { color: var(--ink-2); font-size: .95rem; margin: 0; }
.card-icon {
  width: 40px; height: 40px; border-radius: 11px; display: grid; place-items: center;
  background: var(--red-tint); color: var(--red); margin-bottom: .8rem; font-size: 1.15rem;
}
.card-icon.green { background: var(--green-tint); color: var(--green); }
.card-icon.amber { background: var(--amber-tint); color: var(--amber); }

/* ---------------------------------------------------------------- tables */

.table-tools { display: flex; gap: .7rem; flex-wrap: wrap; align-items: center; margin-bottom: 1rem; }

/* Buttons that sit between a page's opening paragraph and its table.
   They used to be a bare <p> with a 0.2rem top margin and nothing below, so
   the button and the search box underneath it were all but touching — two
   controls of the same size a few pixels apart, which reads as one broken
   row rather than two separate things. */
.page-actions {
  display: flex; flex-wrap: wrap; gap: .55rem;
  margin: 1.1rem 0 1.6rem;
}
.search-input {
  flex: 1 1 240px; padding: .6rem .9rem; border: 1px solid var(--line);
  border-radius: var(--radius-sm); font: inherit; font-size: .93rem; background: #fff;
}
.table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: #fff; }
table { border-collapse: collapse; width: 100%; font-size: .92rem; }
thead th {
  text-align: start; padding: .8rem .9rem; background: var(--bg-2);
  font-weight: 700; font-size: .78rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-3); white-space: nowrap; position: sticky; top: 0;
}
tbody td { padding: .75rem .9rem; border-top: 1px solid var(--line); vertical-align: middle; }
tbody tr:hover { background: var(--bg-2); }
td.num, th.num { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.id-chip {
  font-family: var(--font-latin); font-weight: 700; font-size: .82rem;
  background: var(--bg-2); border: 1px solid var(--line);
  padding: .18rem .5rem; border-radius: 6px; white-space: nowrap;
}
tfoot td { padding: .8rem .9rem; border-top: 2px solid var(--line); font-weight: 800; background: var(--bg-2); }

.pill { display: inline-block; padding: .16rem .55rem; border-radius: 999px; font-size: .76rem; font-weight: 700; }
.pill-paid { background: var(--green-tint); color: var(--green); }
.pill-due { background: var(--amber-tint); color: var(--amber); }

/* ---------------------------------------------------------------- FAQ */

.faq-item { border-bottom: 1px solid var(--line); }
.faq-q {
  width: 100%; text-align: start; background: none; border: 0; cursor: pointer;
  padding: 1.05rem 2.2rem 1.05rem 0; font: inherit; font-weight: 700; color: var(--ink);
  display: block; position: relative;
}
.faq-q::after {
  content: '+'; position: absolute; inset-inline-end: .3rem; top: 50%; transform: translateY(-50%);
  font-size: 1.3rem; color: var(--red); font-weight: 400; line-height: 1;
}
.faq-item[open] .faq-q::after { content: '−'; }
.faq-a { padding: 0 0 1.15rem; color: var(--ink-2); max-width: 74ch; }
.faq-num { color: var(--red); font-family: var(--font-latin); margin-inline-end: .5rem; }

/* ---------------------------------------------------------------- branches */

.branch-card { display: flex; gap: 1rem; align-items: flex-start; }
.branch-badge {
  flex: 0 0 auto; width: 52px; height: 52px; border-radius: 13px;
  background: var(--red-tint); color: var(--red); display: grid; place-items: center;
  font-weight: 800; font-size: .95rem; font-family: var(--font-latin);
}
.branch-card.soon .branch-badge { background: var(--bg-2); color: var(--ink-3); }
.branch-meta { display: flex; gap: 1.2rem; flex-wrap: wrap; margin-top: .7rem; font-size: .87rem; color: var(--ink-3); }
.branch-meta b { color: var(--ink); font-variant-numeric: tabular-nums; }

.notice {
  border: 1px dashed var(--line); border-radius: var(--radius);
  padding: 1.2rem 1.3rem; background: var(--bg-2); color: var(--ink-2);
}
.notice strong { color: var(--ink); }

/* ---------------------------------------------------------------- footer */

.site-footer { background: var(--ink); color: #cfc7cb; padding: 2.8rem 0 1.6rem; margin-top: 3rem; }
.site-footer h4 { color: #fff; font-size: .85rem; text-transform: uppercase; letter-spacing: .07em; margin-bottom: .9rem; }
.site-footer a { color: #f0e8ea; text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
/* Who we are and where the money goes, side by side; then the links.
   Twelve columns because the row divides three ways and the link row divides
   four — the two halves need different splits and one grid has to serve both. */
.footer-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 1.6rem 2rem; }
/* Placed explicitly, on both axes.
   Spans alone were not enough: the items flow in document order, and the bank
   block is fourth in the markup. Dan Noy-Dhar took seven columns, the quick
   links needed seven and would not fit in the five that were left, so they
   wrapped — and the bank block landed on a third row while the space beside
   the first block stayed empty. Naming the row and the start column puts each
   one where it belongs regardless of the order they appear in the HTML. */
.footer-grid > :nth-child(1) { grid-column: 1 / span 7; grid-row: 1; }
.footer-grid > :nth-child(2) { grid-column: 8 / span 5; grid-row: 1; }

/* The four link groups, a quarter each, on their own row.
   Grouped rather than flowed: which link sits beside which used to be an
   accident of how many there were, so "Bank statement" ended up next to
   "Feedback". Each column answers one question now, and the heading says
   which. */
.footer-grid > :nth-child(n + 3) { grid-row: 2; }
.footer-grid > :nth-child(3) { grid-column: 1 / span 3; }
.footer-grid > :nth-child(4) { grid-column: 4 / span 3; }
.footer-grid > :nth-child(5) { grid-column: 7 / span 3; }
.footer-grid > :nth-child(6) { grid-column: 10 / span 3; }

/* Four across needs a wide laptop; below that they pair up, and on a phone
   they stack. A link that wraps mid-phrase is worse than a longer list. */
@media (max-width: 1080px) {
  .footer-grid > :nth-child(3) { grid-column: 1 / span 6; grid-row: 2; }
  .footer-grid > :nth-child(4) { grid-column: 7 / span 6; grid-row: 2; }
  .footer-grid > :nth-child(5) { grid-column: 1 / span 6; grid-row: 3; }
  .footer-grid > :nth-child(6) { grid-column: 7 / span 6; grid-row: 3; }
}

@media (max-width: 780px) {
  .footer-grid { grid-template-columns: 1fr; }
  .footer-grid > * { grid-column: 1 / -1 !important; grid-row: auto !important; }
}

.footer-links { list-style: none; padding: 0; margin: 0; display: grid; gap: .5rem; font-size: .92rem; }
.footer-bank { font-size: .88rem; display: grid; gap: .3rem; }
.footer-bank span { color: #9d9297; }
.footer-bottom {
  border-top: 1px solid #322c2f; margin-top: 2rem; padding-top: 1.2rem;
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  font-size: .84rem; color: #9d9297;
}
.footer-bottom img { width: 18px; height: 18px; border-radius: 4px; display: inline-block; vertical-align: -4px; margin-inline-end: .4rem; }

/* ---------------------------------------------------------------- misc */

.skeleton {
  background: linear-gradient(90deg, var(--bg-2) 25%, #f0eaec 50%, var(--bg-2) 75%);
  background-size: 200% 100%; animation: shimmer 1.4s infinite; border-radius: 6px;
  color: transparent !important;
}
@keyframes shimmer { to { background-position: -200% 0; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

@media print {
  .site-header, .site-footer, .table-tools, .hero-cta { display: none; }
  body { font-size: 11pt; }
}

/* ---------------------------------------------------------------- get the app
   The interstitial every "Apply for a loan" button leads to. Two choices,
   stacked, with the phone app first — a borrower who installs it gets the
   instalment reminders, and a borrower who bookmarks the browser build does
   not. Neither option is hidden: making somebody without an Android phone hunt
   for the way in is exactly the friction this organisation exists to remove.
*/
.platform-list { display: grid; gap: .9rem; margin: 1.8rem 0; }

.platform-card {
  display: flex; align-items: center; gap: 1rem;
  padding: 1.15rem 1.25rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  text-decoration: none;
  color: inherit;
  transition: border-color .15s, transform .15s, box-shadow .15s;
}
.platform-card:hover {
  border-color: var(--red);
  color: inherit;
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(26,22,24,.05), 0 12px 30px rgba(231,34,64,.10);
}
.platform-card.is-primary { border-color: var(--red); background: var(--red-tint); }
.platform-card.is-soon { opacity: .85; cursor: default; box-shadow: none; }
.platform-card.is-soon:hover { border-color: var(--line); transform: none; box-shadow: none; }

/* Set by app.js once the visitor's platform is known. */
.platform-card.is-recommended { border-color: var(--red); background: var(--red-tint); }

.platform-icon { font-size: 1.8rem; line-height: 1; flex: none; }
.platform-body { display: flex; flex-direction: column; gap: .18rem; flex: 1; min-width: 0; }
.platform-body strong { font-size: 1.02rem; }
.platform-body span { color: var(--ink-3); font-size: .93rem; line-height: 1.45; }
.platform-go { color: var(--red); font-size: 1.25rem; flex: none; }

.platform-badge {
  display: inline-block; margin-left: .5rem; padding: .1rem .45rem;
  background: var(--red); color: #fff; border-radius: 100px;
  font-size: .68rem; letter-spacing: .03em; vertical-align: middle;
}

.notice-why { margin-top: 1.6rem; }
.notice-why strong { display: block; margin-bottom: .3rem; }

/* ---------------------------------------------------------------- volunteers
   Kept off the main navigation: nearly everybody here is a student who needs
   money or an alumnus who wants to give, and neither came for a review queue.
*/
.volunteer-strip {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap;
  padding: 1.4rem 1.6rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.volunteer-strip h3 { margin: 0 0 .25rem; font-size: 1.05rem; }
.volunteer-strip p { margin: 0; color: var(--ink-3); font-size: .93rem; max-width: 62ch; }
.volunteer-strip .btn { flex: none; }

@media (max-width: 560px) {
  .platform-card { padding: 1rem; gap: .8rem; }
  .platform-icon { font-size: 1.5rem; }
  .volunteer-strip { padding: 1.2rem; }
  .volunteer-strip .btn { width: 100%; justify-content: center; }
}

/* Branch photographs, added when branches became editable records rather than
   "Branch 01" placeholders. The card was designed badge-left / text-right, so
   the photo spans the full width above both. */
/* The card above is a flex row — badge on the left, text on the right — so the
   photograph has to be a full-basis item that wraps onto its own line rather
   than a third column squeezed in beside them. The negative margins pull it
   out to the card's edges through `.card`'s 1.3rem padding, and `overflow`
   clips it back to the corner radius. */
.branch-card { position: relative; overflow: hidden; flex-wrap: wrap; }
.branch-photo {
  flex: 0 0 auto;
  width: calc(100% + 2.6rem);
  margin: -1.3rem -1.3rem .3rem;
  height: 150px;
  object-fit: cover;
  background: var(--bg-2);
}
.branch-card.soon .branch-photo { filter: grayscale(1); opacity: .75; }
.branch-desc { margin-top: .4rem; color: var(--ink-3); font-size: .9rem; }

/* Management team, hydrated from `public/team`. */
.team-role {
  display: inline-block; margin-bottom: .35rem; padding: .12rem .5rem;
  background: var(--red-tint); color: var(--red); border-radius: 999px;
  font-size: .72rem; font-weight: 700; letter-spacing: .02em;
}

/* Team roll, grouped by the sections the old site used. */
.team-heading { margin: 2.2rem 0 1rem; font-size: 1.05rem; color: var(--red); letter-spacing: .01em; }
.team-heading:first-child { margin-top: 0; }
/* A full-width portrait crop rather than a 96px circle. The stored images are
   300-660px on the long edge; a small round avatar discarded almost all of it,
   which is why the page read as eleven placeholders instead of eleven people.
   `height` and `border-radius` are reset explicitly: an earlier revision of
   this file styled `.team-photo` as a round 72px avatar, and a rule that only
   sets `width` leaves the old height in force — which is how eleven portraits
   came to be drawn as full-width ellipses. */
.team-card {
  padding: 0; overflow: hidden; display: flex; flex-direction: column;
  transition: transform .18s ease, box-shadow .18s ease;
}
.team-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 4px rgba(26, 22, 24, .06), 0 14px 34px rgba(26, 22, 24, .10);
}
.team-photo {
  display: block; width: 100%; height: auto; border-radius: 0;
  aspect-ratio: 4 / 5; object-fit: cover; object-position: center 25%;
  background: var(--bg-2);
}
.team-photo-empty {
  display: grid; place-items: center;
  aspect-ratio: 4 / 5; height: auto; border-radius: 0;
  font-size: 3.4rem; font-weight: 800; color: var(--ink-3);
}
.team-body { padding: 1.1rem 1.2rem 1.3rem; }
.team-body h3 {
  margin: .5rem 0 .3rem; font-size: 1.02rem; line-height: 1.3;
  overflow-wrap: anywhere;
}
.team-body p { margin: 0 0 .4rem; font-size: .9rem; color: var(--ink-3); }
.team-card .id-chip { font-size: .7rem; }

/* Volunteers list several numbers and long institutional addresses. Without
   this a two-number entry pushes a red underline straight through the card
   border, which is the other thing that made this page look unfinished. */
.team-contact {
  display: flex; flex-wrap: wrap; gap: .1rem .55rem;
  font-size: .85rem; margin-top: auto; padding-top: .3rem;
}
.team-contact a { overflow-wrap: anywhere; }

/* Sponsors. A company's mark is not a portrait: it is usually wide, often on a
   white ground, and must not be cropped — a logo with its edges cut off is
   worse than no logo. So `contain` rather than `cover`, and a fixed box it
   sits inside. */
.sponsor-card { display: flex; align-items: center; gap: 1rem; }
.sponsor-logo {
  flex: none; width: 84px; height: 84px;
  object-fit: contain; background: #fff;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: .4rem;
}
/* A company that has not sent a mark yet.
   Its initials, in the fund's green rather than the red used for people — a
   sponsor is an organisation, and the page should not imply a missing
   photograph of somebody. Letter-spacing is negative because two capitals set
   at this size otherwise drift apart. */
.sponsor-logo-empty {
  display: grid; place-items: center;
  font-size: 1.55rem; font-weight: 800; letter-spacing: -.02em;
  color: var(--green); background: var(--green-tint);
  border-color: var(--green-tint); padding: 0;
}
.sponsor-card h3 { margin: 0 0 .2rem; font-size: 1.05rem; }
.sponsor-card h3 a { text-decoration: none; }
.sponsor-card h3 a:hover { text-decoration: underline; }
.sponsor-amount {
  margin: 0; font-family: var(--font-latin);
  font-weight: 800; color: var(--red);
}
[data-sponsors] { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

/* Portraits are the content here, so the cards can be narrower and more of
   them fit a row without any of them shrinking. `[data-founders]` is itself
   the grid; `[data-team]` becomes a sequence of headed grids on hydration, so
   the two need different selectors. */
[data-team] .card-grid,
[data-founders].card-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }

/* Terms pages. Numbering comes from the list so the Bengali gets Bengali
   numerals and a clause can be inserted without renumbering prose by hand. */
.terms-list { counter-reset: clause; list-style: none; padding: 0; margin: 1.6rem 0; }
.terms-list > li {
  counter-increment: clause; position: relative;
  padding: 0 0 1.1rem 2.6rem; margin-bottom: 1.1rem;
  border-bottom: 1px solid var(--line);
}
.terms-list > li:last-child { border-bottom: 0; }
.terms-list > li::before {
  content: counter(clause); position: absolute; inset-inline-start: 0; top: 0;
  width: 1.85rem; height: 1.85rem; border-radius: 50%;
  background: var(--red-tint); color: var(--red);
  display: grid; place-items: center; font-weight: 800; font-size: .82rem;
}
html[lang='bn'] .terms-list > li::before { content: counter(clause, bengali); }

.terms-ways { list-style: none; padding: 0; margin: 1.4rem 0; display: grid; gap: .7rem; }
.terms-ways > li {
  padding: .9rem 1.1rem; background: var(--bg-2);
  border-inline-start: 3px solid var(--green); border-radius: var(--radius-sm);
}

.notice-warn { background: var(--amber-tint); border-color: var(--amber); }
.notice-warn .terms-list { margin: .8rem 0 0; }
.notice-warn .terms-list > li { border-bottom: 0; padding-bottom: .6rem; margin-bottom: .5rem; }
.notice-warn .terms-list > li::before { background: var(--amber); color: #fff; }

/* Faces on the contributor roll. This is the page that thanks people, and a
   column of names alone reads like a spreadsheet of strangers. Where no
   photograph exists the initial keeps the column width steady, so rows do not
   jump about as the table scrolls. */
/* Square, and big enough to be a face rather than a bullet point. A 36px
   circle cropped everybody to a chin and a forehead; at this size a
   photograph is actually of somebody. Square because the photos people send
   are square-ish already, and a circle throws away the corners of every one
   of them. */
.col-avatar { width: 112px; padding-right: 0 !important; }
.row-avatar {
  width: 96px; height: 96px; border-radius: 12px; object-fit: cover;
  background: var(--bg-2); display: inline-grid; place-items: center;
  border: 1px solid var(--line);
}
.row-avatar-empty { font-weight: 700; color: var(--ink-3); font-size: 1.6rem; }

/* Narrow screens get a smaller one: 72px of photograph beside a name and a
   designation leaves the designation two words per line. */
@media (max-width: 560px) {
  .col-avatar { width: 84px; }
  .row-avatar { width: 72px; height: 72px; border-radius: 10px; }
  .row-avatar-empty { font-size: 1.5rem; }
}
td:has(> .row-avatar) { padding-right: 0; }

/* ---------------------------------------------------------------- messages,
   gallery and feedback

   Four pages that carry words and pictures rather than figures. They share the
   card vocabulary the rest of the site already uses, so nothing here invents a
   second visual language for the sake of three components. */

.message-card {
  display: grid; gap: 1.6rem; align-items: start;
  max-width: 92ch;
}
@media (min-width: 720px) { .message-card { grid-template-columns: 300px 1fr; } }

/* The whole photograph, at a size worth printing.
   `height: auto` was already there, so nothing was ever cropped — it was
   simply shown at 148px, which makes any portrait read as a thumbnail. The
   column is twice that now and the image fills it, so a full-length photo
   stays full-length and a square one stays square. */
.message-photo {
  display: block; width: 100%; max-width: 300px; height: auto;
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.message-body h2 { margin: 0 0 .8rem; font-size: 1.25rem; }
/* Generous leading: these are the longest passages of prose on the site, and
   the Bengali face needs the room more than the Latin one does. */
.message-body p {
  margin: 0 0 1.05rem;
  /* Justified, as these letters are set in print. Both edges straight suits a
     signed address from the founder or the chief adviser far better than a
     ragged one, and Bengali justifies more evenly than Latin does.
     `hyphens` keeps the Latin from opening rivers between the words. */
  text-align: justify;
  text-justify: inter-word;
  hyphens: auto;
}
/* The sign-off used to sit at the foot of the letter and was justified with
   it. The justify rule is a class plus an element and the sign-off rule was a
   class alone, so justify won the cascade and stretched the founder's own name
   and phone number across the measure. It is a caption under the
   photograph now, so the rule it needed is gone with it. */

/* The name and role belong to the face, not to the end of the letter. */
.message-caption {
  margin: .9rem 0 0; text-align: center; line-height: 1.45;
}
.message-caption b { display: block; font-size: 1.02rem; }
.message-caption span { color: var(--ink-3); font-size: .93rem; }

.gallery-grid {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
.gallery-item { margin: 0; }
.gallery-item img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--radius-sm); border: 1px solid var(--line);
  background: var(--bg-2);
}
.gallery-item figcaption {
  margin-top: .5rem; font-size: .88rem; color: var(--ink-2);
}

.quote-card {
  margin: 0 0 1rem; padding: 1.25rem 1.4rem;
  background: var(--card); border: 1px solid var(--line);
  border-inline-start: 3px solid var(--green);
  border-radius: var(--radius-sm); box-shadow: var(--shadow);
  max-width: 74ch;
}
.quote-card p { margin: 0 0 .8rem; }
.quote-card footer { font-size: .9rem; }

/* Icon-only header buttons — the two Facebook links.
   Square rather than pill so they read as icons beside the text buttons, and
   the badge distinguishes the group from the page without a second glyph. */
.btn-icon {
  padding: .45rem; width: 34px; height: 34px;
  position: relative; color: var(--ink-2);
}
.btn-icon:hover { color: #1877f2; border-color: #1877f2; }
.btn-icon svg { display: block; }
.btn-badge {
  position: absolute; inset-block-start: -4px; inset-inline-end: -4px;
  background: var(--green); color: #fff;
  width: 14px; height: 14px; border-radius: 50%;
  font-size: .62rem; font-weight: 800; line-height: 14px; text-align: center;
}
/* Giving is the green action; applying for a loan stays the red one, so the
   two calls to action in the header are never mistaken for each other. */
.btn-green { background: var(--green); color: #fff; }
.btn-green:hover { background: #005440; color: #fff; }

/* ---------------------------------------------------------------- banner */

/* The organisation's own artwork, inside the hero rather than stacked above it.
   On a wide screen it sits beside the heading — the picture and the sentence
   make the same point, and side by side they make it once instead of twice.
   Below the hero breakpoint the grid collapses to one column and the banner
   goes first, because on a phone the image is the faster read.

   Explicit width and height in the markup reserve the space before it loads,
   so the heading does not jump as it arrives. */
.hero-banner {
  width: 100%; height: auto;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  align-self: center;
}
@media (max-width: 860px) {
  .hero-banner { order: -1; margin-bottom: 1.2rem; }
  .hero-grid { display: flex; flex-direction: column; }
}

/* ---------------------------------------------------------------- press */

.press-grid { display: grid; gap: 1.6rem; align-items: start; }
@media (min-width: 760px) { .press-grid { grid-template-columns: 300px 1fr; } }

.press-clip { display: block; }
.press-clip img {
  width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: #fff;
}
.press-source {
  font-size: .82rem; color: var(--ink-3); font-weight: 700;
  letter-spacing: .02em; margin-bottom: .3rem;
}
.press-body h3 { font-size: 1.3rem; margin-bottom: .6rem; }

/* --------------------------------------------------- header, condensed

   Scrolling down hides the buttons and shrinks the mark, leaving the name and
   the menu; scrolling back up returns them. A sticky header that keeps its
   full height eats a third of a phone screen, and the buttons are the part
   somebody is least likely to want while reading.

   The sizes are transitioned but the row change is not — a grid re-flow cannot
   be animated, and a half-animated header that lands wrong is worse than one
   that simply snaps. */
/* The mark scales as one piece.
   Scaling the logo and the text separately was the mistake: a transform does
   not change the space an element occupies, so the logo shrank visually while
   its 74px footprint stayed, and a gap opened between it and the name. Scaling
   the whole .brand keeps every distance inside it in proportion — the motto
   included, which now stays visible in the small state instead of being hidden
   to cover the problem. */
.site-header .brand {
  transform-origin: left center;
  transition: transform .28s cubic-bezier(.2, .7, .3, 1);
  will-change: transform;
}

/* Row one leaves by sliding and fading rather than being switched off.
   display:none cannot be animated, so the row vanished between two frames
   and the page below jumped up to meet it. */
.site-header .header-actions {
  overflow: hidden;
  transition: max-height .28s cubic-bezier(.2, .7, .3, 1),
              opacity .18s ease,
              transform .28s cubic-bezier(.2, .7, .3, 1),
              margin-bottom .28s cubic-bezier(.2, .7, .3, 1);
  max-height: 60px;
}

/* Row one slides up and fades as the mark shrinks, so the two happen together
   and read as one movement rather than a disappearance followed by a jump. */
.site-header.condensed .header-actions {
  max-height: 0;
  opacity: 0;
  transform: translateY(-8px);
  margin-bottom: 0;
  pointer-events: none;
}

/* The whole mark, scaled as one piece — logo, name and motto keeping every
   distance between them. The motto stays visible; it was only ever hidden to
   cover the gap that separate scaling opened up. */
.site-header.condensed .brand { transform: scale(.76); }

@media (min-width: 941px) {
  .site-header.condensed .brand { transform: scale(.64); }
}

@media (min-width: 941px) {
  /* One row: the mark at the left, the menu at the right. */
  .site-header.condensed .header-in { grid-template-rows: auto; row-gap: 0; }
  .site-header.condensed .brand { grid-row: 1; }
  .site-header.condensed .nav { grid-row: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .site-header .brand,
  .site-header .header-actions { transition: none; }
}

/* ------------------------------------------------------- facebook reviews

   A row of phone-shaped cards that scrolls sideways. Native overflow rather
   than a carousel: it works with a finger, a trackpad, a scrollbar and the
   arrow keys, costs no JavaScript, and cannot get stuck half way between
   slides the way a stepped carousel can. */
.review-rail {
  display: flex; gap: 1rem;
  overflow-x: auto; scroll-snap-type: x mandatory;
  padding: .25rem .25rem 1rem;
  scrollbar-width: thin;
  /* The cards are the point; let them run to the edge of the screen. */
  margin-inline: calc(-1 * clamp(.5rem, 2vw, 1.25rem));
  padding-inline: clamp(.5rem, 2vw, 1.25rem);
}
.review-rail:focus-visible { outline: 3px solid var(--red); outline-offset: 4px; border-radius: var(--radius); }

.review-card {
  margin: 0; flex: 0 0 auto;
  width: clamp(190px, 44vw, 240px);
  scroll-snap-align: start;
}
.review-card img {
  width: 100%; aspect-ratio: 895 / 1801; object-fit: cover; object-position: top;
  border: 1px solid var(--line); border-radius: 18px;
  background: var(--bg-2); cursor: zoom-in;
  box-shadow: var(--shadow);
}
.rail-hint { font-size: .85rem; margin-top: -.4rem; }

/* ------------------------------------------------------------ feedback form */

.feedback-form {
  display: flex; flex-direction: column; gap: .9rem;
  max-width: 56ch; margin: 1.2rem 0 2rem;
  padding: 1.3rem 1.4rem;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.feedback-form h3 { margin: 0; }
.feedback-form label { display: flex; flex-direction: column; gap: .35rem; font-weight: 600; font-size: .92rem; }
.feedback-form textarea,
.feedback-form input[type='text'] {
  font: inherit; padding: .6rem .7rem;
  border: 1px solid var(--line-strong, var(--line)); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--ink);
}
.feedback-form textarea { resize: vertical; }
.feedback-kind {
  border: 0; padding: 0; margin: 0;
  display: flex; gap: 1.2rem; flex-wrap: wrap;
}
.feedback-kind label { flex-direction: row; align-items: center; gap: .4rem; font-weight: 500; }
.feedback-anon { flex-direction: row; align-items: flex-start; gap: .5rem; font-weight: 500; }
.feedback-preview img {
  width: 72px; height: 72px; object-fit: cover;
  border-radius: 50%; border: 1px solid var(--line);
}

/* The face beside a published quote. Small on purpose — it says who, and the
   words are what the page is for. */
.quote-card footer { display: flex; align-items: center; gap: .7rem; }
.quote-face {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  object-fit: cover; border: 1px solid var(--line);
}
.quote-face-empty {
  display: grid; place-items: center;
  background: var(--green-tint); color: var(--green);
  font-weight: 800; font-size: 1.05rem;
}
.quote-who { line-height: 1.35; }

/* ------------------------------------------------------------------ credits

   Who built the site and the apps. Two cards, each a logo beside a short
   paragraph — the same card vocabulary the rest of the site uses, so nothing
   here invents a new one. */
.credit-card {
  display: flex; gap: 1.1rem; align-items: flex-start;
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: 14px; padding: 1.1rem 1.2rem; margin: 1.1rem 0;
}
.credit-logo {
  width: 96px; height: 96px; flex: 0 0 96px;
  border-radius: 12px; object-fit: contain; background: var(--bg-2);
}
.credit-body { min-width: 0; }
.credit-body h2 { margin: 0 0 .15rem; font-size: 1.25rem; }
.credit-kicker {
  margin: 0 0 .55rem; color: var(--ink-3);
  font-size: .92rem; font-weight: 600;
}
.credit-body p { margin: 0 0 .7rem; }
.credit-links { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; }
.credit-heading { margin-top: 2rem; }

/* A 96px logo beside text leaves the text three words wide on a phone. */
@media (max-width: 560px) {
  .credit-card { flex-direction: column; gap: .8rem; }
  .credit-logo { width: 72px; height: 72px; flex-basis: auto; }
}

/* The photograph and its caption travel together. */
.message-figure { margin: 0; }
